Files
Database/MLD/MLD_PAC.SRC
Erik Groener a3623ca1ef FCLT#74251 Configuratiemogelijkheden voor meldingskenmerken naar opdrachten
svn path=/Database/trunk/; revision=58688
2023-01-17 11:39:14 +00:00

4049 lines
208 KiB
Plaintext
Raw Blame History

#ifdef MLD
/*
* $Revision$
* $Id$
*/
#undef TRUNC
CREATE OR REPLACE PACKAGE mld AS
PROCEDURE updatemeldingstatus (meldingkey IN NUMBER,
closeit IN NUMBER,
user_key IN NUMBER);
PROCEDURE updatemeldingstatusAV (meldingkey IN number, closeit IN number, user_key IN number, autoav IN number);
FUNCTION getmeldingstatusdate (pmeldingkey IN number, pstatus IN number) RETURN date;
FUNCTION getmeldinguser (pmeldingkey IN number) RETURN NUMBER;
PROCEDURE setmeldingstatus (pmeldingkey IN NUMBER, pstatus IN NUMBER, puserkey IN NUMBER, pnotificeren IN NUMBER DEFAULT 1);
FUNCTION getopdrachtstatusdate (popdrkey IN number, pstatus IN number) RETURN date;
PROCEDURE setopdrachtstatus (popdrachtkey IN NUMBER, pstatus IN NUMBER, puserkey IN NUMBER);
PROCEDURE notifybackoffice (pmeldingkey IN NUMBER, pcode IN VARCHAR2, pdisc_level IN NUMBER DEFAULT 1);
PROCEDURE notifyprio (pmeldingkey IN NUMBER, prio IN NUMBER, pperslid_key IN NUMBER, pdisc_level IN NUMBER DEFAULT 1);
PROCEDURE notifyopdrgoedkeurders (popdrkey IN NUMBER);
FUNCTION mld_besteed_budget_pgb (p_prs_key IN NUMBER, p_disc_key IN NUMBER)
RETURN NUMBER;
FUNCTION mld_besteed_budget_agb (p_kp_key IN NUMBER)
RETURN NUMBER;
PROCEDURE mld_addautoorder (p_melding_key IN NUMBER);
PROCEDURE mld_nextworkflowstep (p_melding_key IN NUMBER
,p_success IN NUMBER);
FUNCTION getlowestobjectuitvoer (p_melding_key IN NUMBER) RETURN NUMBER;
FUNCTION uitvoertijd_to_char (uitvoertijd IN MLD_T_UITVOERTIJD) RETURN VARCHAR;
FUNCTION geteinddatum (startdate IN DATE,
stdm_key IN NUMBER,
prio IN NUMBER,
alg_key IN NUMBER,
ins_key IN NUMBER,
uitvoertijd_object IN MLD_T_UITVOERTIJD DEFAULT MLD_T_UITVOERTIJD(NULL, NULL)) RETURN DATE;
FUNCTION geteinddatum (p_melding_key IN NUMBER,
p_uitvoertijd_object IN MLD_T_UITVOERTIJD DEFAULT MLD_T_UITVOERTIJD(NULL, NULL),
p_startdate IN DATE DEFAULT NULL) RETURN DATE;
FUNCTION getactualuitvoer (startdate IN DATE,
enddate IN DATE,
stdm_key IN NUMBER,
prio IN NUMBER,
alg_key IN NUMBER,
ins_key IN NUMBER,
eenheid IN VARCHAR2 DEFAULT NULL
) RETURN MLD_T_UITVOERTIJD;
FUNCTION getactualuitvoer (p_melding_key IN NUMBER) RETURN MLD_T_UITVOERTIJD;
FUNCTION getstduitvoer (stdm_key IN NUMBER,
prio IN NUMBER,
alg_key IN NUMBER,
ins_key IN NUMBER) RETURN MLD_T_UITVOERTIJD;
FUNCTION getstduitvoer (p_melding_key IN NUMBER) RETURN MLD_T_UITVOERTIJD;
PROCEDURE getSLAparams (stdm_key IN NUMBER,
prio IN NUMBER,
alg_key IN NUMBER, -- Altijd gebouw of hoger, locatie niet ondersteund
ins_key IN NUMBER,
v_mld_stdmelding_regime OUT NUMBER,
v_uitvoertijd_object OUT MLD_T_UITVOERTIJD,
v_beginuur OUT NUMBER,
v_einduur OUT NUMBER,
v_werkdagen OUT NUMBER
);
FUNCTION getacceptdatum (startdate IN DATE, stdm_key IN NUMBER, alg_key IN NUMBER, p_prio IN NUMBER DEFAULT 3) RETURN DATE;
FUNCTION getnettotijdsbesteding (p_opdr_key IN NUMBER, p_prs_key IN NUMBER DEFAULT NULL) RETURN NUMBER;
FUNCTION bepaalopdrmeldingvolgnr (p_melding_key IN NUMBER) RETURN NUMBER;
FUNCTION bepaalopdrcontractvolgnr (p_contract_key IN NUMBER) RETURN NUMBER;
FUNCTION mldsprintf (ps IN VARCHAR2, p_melding_key IN NUMBER) RETURN VARCHAR2;
FUNCTION opdrsprintf (ps IN VARCHAR2, p_opdr_key IN NUMBER) RETURN VARCHAR2;
PROCEDURE upsertmeldingkenmerk (p_kenmerk_key IN NUMBER,
p_mld_key IN NUMBER,
p_waarde IN VARCHAR2);
PROCEDURE upsertopdrachtkenmerk (p_kenmerk_key IN NUMBER,
p_opdr_key IN NUMBER,
p_waarde IN VARCHAR2);
FUNCTION mldflexsummary (pmelding_key IN NUMBER) RETURN VARCHAR2;
PROCEDURE remove(p_melding_key IN NUMBER);
PROCEDURE remove_opdr(p_mld_opdr_key IN NUMBER);
END mld;
/
CREATE OR REPLACE PACKAGE BODY mld AS
PROCEDURE updatemeldingstatusAV (meldingkey IN number, closeit IN number, user_key IN number, autoav IN number)
AS
openopdrachten number;
opdrachten number;
nietavopdrachten number;
BEGIN
-- Als closeit=1 dan wordt de melding afgesloten als dat al niet zo was
-- Anders:
-- Als er open opdrachten zijn wordt de melding op Uitgegeven gezet als dat al niet zo was
-- Als er uitsluitend Verwerkte opdrachten zijn, dan worden de melding ook verwerkt als dat al niet zo was
-- maar alleen als autoav=1. Men kan er voor kiezen dat zelf te regelen (AAIT#24697)
-- It needs typically to be called after changes in mld_opdr.
IF closeit = 1
THEN
setmeldingstatus (meldingkey, 5, user_key);
ELSE
SELECT COUNT ( * )
INTO openopdrachten
FROM mld_opdr
WHERE mld_melding_key = meldingkey AND mld_statusopdr_key NOT IN (1, 2, 6, 7, 9);
IF openopdrachten > 0
THEN
-- als melding geaccepteerd was wordt deze nu (vanwege open opdrachten) uitgegeven
-- als melding al Uitgevoerd was wordt deze nu (met in behandeling opdrachten) NIET weer uitgegeven!
setmeldingstatus (meldingkey, 7, user_key);
ELSE
-- Er zijn dus geen actieve opdrachten, maar er zijn wellicht wel dichte opdrachten
-- Die hebben echter status 1 (Afgewezen), 6 (Afgemeld) of 7 (Verwerkt), 9 (Afgerond)
-- De melding mag dan naar AV indien er louter 7 (minstens 1) en 1 opdrachten zijn
SELECT COUNT ( * )
INTO opdrachten
FROM mld_opdr
WHERE mld_melding_key = meldingkey;
SELECT COUNT ( * )
INTO nietavopdrachten
FROM mld_opdr
WHERE mld_melding_key = meldingkey AND mld_statusopdr_key <> 7;
-- verwerkteopdrachten := opdrachten - nietavopdrachten;
IF nietavopdrachten = 0 AND opdrachten > 0
THEN
IF autoav = 1
THEN
-- There are only orders that are adm. closed, close the call (AV)
setmeldingstatus (meldingkey, 6, user_key);
END IF;
ELSE
-- Er zijn alleen opdrachten met status 1 (Afgewezen) of 6/9 (Afgemeld/Afgerond),
-- dan zetten we de Melding hier terug naar Geaccepteerd indien die Uitgegeven was
-- Zodat die bij de FO weer onder Inbehandeling valt.
setmeldingstatus (meldingkey, 4, user_key);
END IF;
END IF;
END IF;
END;
-- Om helemaal compatible te blijven
PROCEDURE updatemeldingstatus (meldingkey IN number, closeit IN number, user_key IN number)
AS
BEGIN
updatemeldingstatusAV (meldingkey, closeit, user_key, 1);
END;
-- Geef de datum waarop de melding op status pstatus is gezet
-- Alleen bedoeld voor secundaire statussen (datum van registratie is bv wel
-- direct te bepalen), dus alleen voor 1,4,5,6. Dit zijn tevens de
-- actions die eenmalig zijn. reden voor deze functie: Ik wil niet dat iedereen die
-- deze info wil zelf in de tracking moet gaan zoeken.
FUNCTION getmeldingstatusdate (pmeldingkey IN number, pstatus IN number) RETURN date
AS
eventcode fac_srtnotificatie.fac_srtnotificatie_code%TYPE := NULL;
retdatum date := NULL;
BEGIN
-- Welke tag hoort bij de gevraagde status?
CASE pstatus
WHEN 1 -- Afgewezen
THEN
eventcode := 'MLDREJ';
WHEN 4 -- Geaccepteerd (ongezien of gezien)
THEN
eventcode := 'MLDACP';
WHEN 5 -- Afgemeld
THEN
eventcode := 'MLDAFM';
WHEN 6 -- Verwerkt
THEN
eventcode := 'MLDVER';
ELSE NULL;
END CASE;
IF eventcode IS NOT NULL THEN
retdatum := fac.gettrackingdate(eventcode, pmeldingkey);
END IF;
RETURN retdatum;
END;
-- Niet veel gebruikt, maar voor compatibility gedefinieerd
-- wellicht nog uit te breiden tot de user per status, als wenselijk
FUNCTION getmeldinguser (pmeldingkey IN number) RETURN number
AS
perslid_key fac_tracking.prs_perslid_key%TYPE := NULL;
BEGIN
perslid_key := fac.gettrackinguserkey('MLDNEW', pmeldingkey);
RETURN perslid_key;
END;
-- Geef meldingkey, gewenste status en userkey, en de status wordt
-- gezet, waarbij zonodig (indien verandering) een trackrecord wordt gemaakt
-- Als de status niet wijzigt, wordt ook geen trackrecord gemaakt
-- ZIE schema StateDiagramOpdrachten.vsd
-- Onderliggende childmeldingen krijgen dezelfde status, wat normaliter
-- zou moeten lukken
PROCEDURE setmeldingstatus (pmeldingkey IN NUMBER, pstatus IN NUMBER, puserkey IN NUMBER, pnotificeren IN NUMBER DEFAULT 1)
AS
currentstatus mld_melding.mld_melding_status%TYPE;
activiteit_key mld_melding.fac_activiteit_key%TYPE;
newstatus mld_melding.mld_melding_status%TYPE;
eventcode VARCHAR2(10); -- tabelsize is 6
clear_on_close NUMBER(2); -- +1 = Attentie, +2 = Behandelaar , +4 = Actieve behandelgroep, +8 = Actieve behandelaar
actiecode mld_melding.mld_melding_actiecode%TYPE;
behandelaar_key mld_melding.mld_melding_behandelaar_key%TYPE;
discipline_key mld_melding.mld_ins_discipline_key%TYPE;
behandelaar2_key mld_melding.mld_melding_behandelaar2_key%TYPE;
CURSOR c_mldchilderen
IS
SELECT mld_melding_key
FROM mld_melding
WHERE mld_melding_parentkey = pmeldingkey;
BEGIN
SELECT mld_melding_status, fac_activiteit_key, mld_melding_actiecode, mld_melding_behandelaar_key, mld_ins_discipline_key, mld_melding_behandelaar2_key
INTO currentstatus, activiteit_key, actiecode, behandelaar_key, discipline_key, behandelaar2_key
FROM mld_melding
WHERE mld_melding_key = pmeldingkey;
CASE pstatus
WHEN 0 -- Pending
THEN
IF currentstatus IS NULL
THEN
newstatus := pstatus;
eventcode := 'MLDNEW';
ELSIF currentstatus = 2 OR currentstatus = 4
THEN
newstatus := pstatus;
eventcode := 'MLDBWD';
END IF;
WHEN 1 -- Afgewezen
THEN
IF currentstatus IS NULL OR currentstatus = 0 OR currentstatus = 2
THEN
newstatus := pstatus;
eventcode := 'MLDREJ';
clear_on_close := fac.getsetting('mld_clear_on_close');
IF BITAND(clear_on_close, 1) = 1
THEN
actiecode := 1;
END IF;
IF BITAND(clear_on_close, 2) = 2
THEN
behandelaar_key := NULL;
END IF;
IF BITAND(clear_on_close, 4) = 4
THEN
discipline_key := NULL;
END IF;
IF BITAND(clear_on_close, 8) = 8
THEN
behandelaar2_key := NULL;
END IF;
END IF;
WHEN 2 -- Ingevoerd
THEN
IF currentstatus IS NULL OR currentstatus = 1
THEN
newstatus := pstatus;
eventcode := 'MLDNEW';
ELSIF currentstatus = 0
THEN
newstatus := pstatus;
eventcode := 'MLDDOO';
ELSIF currentstatus = 4 OR currentstatus = 7 -- mld_disc_params_keten of mld_forward_if_active
THEN
newstatus := pstatus;
eventcode := 'MLDFWD';
END IF;
WHEN 4 -- Geaccepteerd (ongezien of gezien)
THEN
IF currentstatus = 2
THEN
newstatus := pstatus;
eventcode := 'MLDACP';
ELSIF currentstatus = 7
THEN
newstatus := pstatus;
eventcode := NULL; -- Terug van uitgegeven is geen meldingstatuswijziging
END IF;
WHEN 5 -- Afgemeld
THEN
IF currentstatus = 2 OR currentstatus = 0 OR currentstatus = 4 OR currentstatus = 7
THEN
newstatus := pstatus;
eventcode := 'MLDAFM';
clear_on_close := fac.getsetting('mld_clear_on_close');
IF BITAND(clear_on_close, 1) = 1
THEN
actiecode := 1;
END IF;
IF BITAND(clear_on_close, 2) = 2
THEN
behandelaar_key := NULL;
END IF;
IF BITAND(clear_on_close, 4) = 4
THEN
discipline_key := NULL;
END IF;
IF BITAND(clear_on_close, 8) = 8
THEN
behandelaar2_key := NULL;
END IF;
END IF;
WHEN 6 -- Verwerkt
THEN
IF currentstatus = 5
THEN
newstatus := pstatus;
eventcode := 'MLDVER';
END IF;
WHEN 7 -- Uitgegeven
THEN
IF currentstatus = 4
THEN
newstatus := pstatus;
-- eventcode := 'MLDUIT';
END IF;
ELSE
-- Invalid statuschange or no change
newstatus := NULL;
END CASE;
IF newstatus IS NOT NULL
THEN
-- vooralsnog lopen de notificaties 1-op-1 met de tracking
-- noticode := eventcode;
UPDATE mld_melding
SET mld_melding_status = newstatus,
mld_melding_actiecode = actiecode,
mld_melding_behandelaar_key = behandelaar_key,
mld_ins_discipline_key = discipline_key,
mld_melding_behandelaar2_key = behandelaar2_key
WHERE mld_melding_key = pmeldingkey;
IF activiteit_key > 0
THEN
RETURN;
END IF;
IF eventcode = 'MLDAFM'
THEN
fac.createlikebookmark ('melding', pmeldingkey);
ELSIF newstatus <> 0 AND newstatus <> 3 AND fac.getsetting('mld_notify_retract') = 1
THEN
fac.clrnotifications('MLDNW_', pmeldingkey, NULL, 'MLDACP');
END IF;
IF pnotificeren = 0 AND eventcode = 'MLDAFM'
THEN
eventcode := '#' || eventcode;
END IF;
-- We know that trackaction doesn't do tracking if eventcode is null
fac.trackaction (eventcode, pmeldingkey, puserkey, NULL, NULL);
FOR r IN c_mldchilderen
LOOP
UPDATE mld_melding
SET mld_melding_status = newstatus
WHERE mld_melding_key = r.mld_melding_key;
IF eventcode = 'MLDAFM' OR eventcode = '#MLDAFM'
THEN
fac.createlikebookmark ('melding', r.mld_melding_key);
ELSIF newstatus <> 0 AND newstatus <> 3 AND fac.getsetting('mld_notify_retract') = 1
THEN
fac.clrnotifications('MLDNW_', r.mld_melding_key, NULL, 'MLDACP');
END IF;
fac.trackaction (eventcode, r.mld_melding_key, puserkey, NULL, NULL);
END LOOP;
END IF;
END;
/* Deze functie is handig maar is amper toepasbaar bij intensieve queries */
FUNCTION getopdrachtstatusdate (popdrkey IN number, pstatus IN number) RETURN date
AS
eventcode fac_srtnotificatie.fac_srtnotificatie_code%TYPE := NULL;
retdatum date := NULL;
BEGIN
-- Welke tag hoort bij de gevraagde status?
CASE pstatus
WHEN 1
THEN
eventcode := 'ORDCAN';
WHEN 2
THEN
eventcode := 'ORDFNO'; -- of ORDFNGO of ORDOOK
WHEN 3
THEN
eventcode := 'ORDFIA';
WHEN 4
THEN
eventcode := 'ORDFOK';
WHEN 5
THEN
eventcode := 'ORDNEW';
WHEN 6 -- Afgemeld
THEN
eventcode := 'ORDAFM';
WHEN 7 -- Verwerkt
THEN
eventcode := 'ORDVER';
WHEN 9 -- Kosten Afgemeld
THEN
eventcode := 'ORDAFR'; -- of ORDOOK
WHEN 8
THEN
eventcode := 'ORDACP';
WHEN 10 -- Ter goedkeuring
THEN
eventcode := 'ORDGOE';
ELSE NULL;
END CASE;
IF eventcode IS NOT NULL THEN
retdatum := fac.gettrackingdate(eventcode, popdrkey);
END IF;
RETURN retdatum;
END;
-- Geef opdrachtkey, gewenste status en userkey, en de status wortdt
-- gezet, waarbij zonodig (indien verandering) een trackrecord wordt gemaakt
-- Als de status niet wijzigt, wordt ook geen trackrecord gemaakt
-- ZIE schema StateDiagramOpdrachten.vsd
PROCEDURE setopdrachtstatus (popdrachtkey IN NUMBER, pstatus IN NUMBER, puserkey IN NUMBER)
AS
currentstatus mld_opdr.mld_statusopdr_key%TYPE;
newstatus mld_opdr.mld_statusopdr_key%TYPE;
eventcode fac_srtnotificatie.fac_srtnotificatie_code%TYPE;
typeopdr_key mld_typeopdr.mld_typeopdr_key%TYPE;
typeopdr_isofferte mld_typeopdr.mld_typeopdr_isofferte%TYPE;
statusopdr_key_refiat mld_opdr.mld_statusopdr_key_refiat%TYPE;
BEGIN
SELECT mld_statusopdr_key, mld_typeopdr_key, mld_statusopdr_key_refiat
INTO currentstatus, typeopdr_key, statusopdr_key_refiat
FROM mld_opdr
WHERE mld_opdr_key = popdrachtkey;
CASE pstatus
WHEN 1 -- Verworpen
THEN
IF currentstatus = 2
THEN
newstatus := pstatus;
eventcode := 'ORDREJ';
ELSIF currentstatus = 4 OR currentstatus = 5 OR currentstatus = 8 -- Verwerpen vanuit status Gefiatteerd(4) alleen door Putorders (fac.markorderassent).
THEN
newstatus := pstatus;
eventcode := 'ORDCAN';
END IF;
WHEN 2 -- Niet gefiatteerd/niet goedgekeurd
THEN
IF currentstatus = 3
THEN
newstatus := pstatus;
eventcode := 'ORDFNO';
ELSIF currentstatus = 6
THEN
-- dit (van 6 naar 2) kan nu alleen igv offerte
-- bij uitbreiding zonodig gaan kijken naar isofferte
-- om het onderscheid te bepalen
newstatus := pstatus;
eventcode := 'ORDONO'; -- Offerte afgewezen
ELSIF currentstatus = 10
THEN
newstatus := pstatus;
eventcode := 'ORDGNO';
END IF;
WHEN 3 -- Ter fiattering
THEN
IF currentstatus IS NULL OR currentstatus = 10 OR
currentstatus = 5 OR currentstatus = 6 OR currentstatus = 8 OR currentstatus = 9 -- Hergoedkeuring/Herfiattering.
THEN
newstatus := pstatus;
eventcode := 'ORDFIA';
END IF;
WHEN 4 -- Gefiatteerd
THEN
IF currentstatus = 3
THEN
newstatus := pstatus;
eventcode := 'ORDFOK';
END IF;
WHEN 5 -- Uitgegeven
THEN
-- Eerste keer goedkeuren/fiateren komt van currentstatus NULL, 4 of 10.
-- Terugkomen van hergoedkeuring/herfiattering/ komt van currentstatus 3 (afgewezen), 4 of 10.
IF currentstatus IS NULL OR currentstatus = 3 OR currentstatus = 4 OR currentstatus = 10
THEN
newstatus := pstatus;
eventcode := 'ORDNEW';
END IF;
WHEN 6 -- Proces Technisch voltooid (TV) (Afgemeld)
THEN
-- Terugkomen van hergoedkeuring/herfiattering/ komt van currentstatus 3 (afgewezen), 4 of 10.
IF currentstatus = 3 OR currentstatus = 4 OR currentstatus = 5 OR currentstatus = 8 OR currentstatus = 10
THEN
newstatus := pstatus;
eventcode := 'ORDAFM';
END IF;
WHEN 7 -- Administratief voltooid (AV) (Verwerkt)
THEN
IF currentstatus = 6 OR currentstatus = 9
THEN
newstatus := pstatus;
eventcode := 'ORDVER';
END IF;
WHEN 8 -- Geaccepteerd door de uitvoerder
THEN
-- Terugkomen van hergoedkeuring/herfiattering/ komt van currentstatus 3 (afgewezen), 4 of 10.
IF currentstatus = 3 OR currentstatus = 4 OR currentstatus = 5 OR currentstatus = 10
THEN
newstatus := pstatus;
eventcode := 'ORDACP';
END IF;
WHEN 9 -- Kosten Voltooid (Afgerond) of Offerte Ok
THEN
-- Terugkomen van hergoedkeuring/herfiattering/ komt van currentstatus 3 (afgewezen), 4 of 10.
IF currentstatus = 3 OR currentstatus = 4 OR currentstatus = 6 OR currentstatus = 10
THEN
newstatus := pstatus;
-- CHECK OP OFFERTEAANVRAAG
SELECT mld_typeopdr_isofferte
INTO typeopdr_isofferte
FROM mld_typeopdr
WHERE mld_typeopdr_key = typeopdr_key;
-- exceptions? ik gok van niet.
IF typeopdr_isofferte = 1
THEN
eventcode := 'ORDOOK'; -- offerte ok
ELSE
eventcode := 'ORDAFR'; -- kosten voltooid
END IF;
END IF;
WHEN 10 -- Ter goedkeuring
THEN
IF currentstatus IS NULL OR
currentstatus = 5 OR currentstatus = 6 OR currentstatus = 8 OR currentstatus = 9 -- Hergoedkeuring/Herfiattering.
THEN
newstatus := pstatus;
eventcode := 'ORDGOE';
END IF;
ELSE
-- Invalid statuschange or no change
newstatus := NULL;
END CASE;
IF newstatus IS NOT NULL
THEN
-- vooralsnog lopen de notificaties 1-op-1 met de tracking
-- noticode := eventcode;
UPDATE mld_opdr
SET mld_statusopdr_key = newstatus
WHERE mld_opdr_key = popdrachtkey;
-- We know that trackaction doesnt do tracking if eventcode is null
-- Bij hergoedkeuring/herfiattering alleen het fiatteren en goedkeuren tracken.
IF statusopdr_key_refiat IS NULL OR
newstatus = 3 OR newstatus = 4 OR newstatus = 10
THEN
fac.trackaction (eventcode, popdrachtkey, puserkey, NULL, NULL);
END IF;
END IF;
END;
-- Stuur alle mogelijke backofficemedewerkers een bericht als de
-- melding NIEUW is of geaccepteerd wordt door MLDBO3.
-- Naar wie, wordt reversed opgezocht op basis van toegekende autorisaties
-- (zoals bij de lijst van BO-behandelaars in suggest/persoonfilter.inc)
PROCEDURE notifybackoffice (pmeldingkey IN NUMBER, pcode IN VARCHAR2, pdisc_level IN NUMBER DEFAULT 1)
AS
lloc_key mld_melding.mld_alg_locatie_key%TYPE;
lonrg_key mld_melding.mld_alg_onroerendgoed_keys%TYPE;
lalg_type alg_v_onroerendgoed.alg_type%TYPE;
lafd_key prs_perslid.prs_afdeling_key%TYPE;
ldisc_key mld_disc_params.mld_ins_discipline_key%TYPE;
lspoed mld_melding.mld_melding_spoed%TYPE;
lnotiprio NUMBER (1);
loms2bo fac_srtnotificatie.fac_srtnotificatie_oms%TYPE;
loms2b3 fac_srtnotificatie.fac_srtnotificatie_oms%TYPE;
lomsbhg fac_srtnotificatie.fac_srtnotificatie_oms%TYPE;
loms2bp fac_srtnotificatie.fac_srtnotificatie_oms%TYPE;
l2bomode fac_srtnotificatie.fac_srtnotificatie_mode%TYPE;
l2b3mode fac_srtnotificatie.fac_srtnotificatie_mode%TYPE;
lbhgmode fac_srtnotificatie.fac_srtnotificatie_mode%TYPE;
l2bpmode fac_srtnotificatie.fac_srtnotificatie_mode%TYPE := 0;
lbonotify mld_disc_params.mld_disc_params_bonotify%TYPE;
lbhgnotify mld_disc_params.mld_disc_params_bhgnotify%TYPE;
lfunctiecode fac_functie.fac_functie_code%TYPE;
lsrtnoticode fac_srtnotificatie.fac_srtnotificatie_code%TYPE;
lstatus mld_melding.mld_melding_status%TYPE;
lbehandelaar mld_melding.mld_melding_behandelaar2_key%TYPE;
bericht VARCHAR2 (4000); -- fac_srtnotificatie_oms%TYPE kan te kort zijn na substitutie
priobericht VARCHAR2 (4000); -- fac_srtnotificatie_oms%TYPE kan te kort zijn na substitutie
lnrreceivers NUMBER;
lreceivers fac_srtnotificatie.fac_srtnotificatie_oms%TYPE;
lreceivers1 fac_srtnotificatie.fac_srtnotificatie_oms%TYPE;
ltracking VARCHAR2 (4000); -- moet tijdelijk groter dan fac_srtnotificatie.fac_srtnotificatie_oms%TYPE kunnen zijn
lnotifyooh mld_disc_params.mld_disc_params_offhours%TYPE;
lsender mld_discipline.ins_discipline_email%TYPE;
BEGIN
BEGIN
-- De vakgroep (discipline) setting MLD_DISC_PARAMS_BONOTIFY geeft aan of de notificatie moeten worden verstuurd.
-- MLD_DISC_PARAMS_BONOTIFY: 0=niet, 1=bof, 2=bo3, 3=bo3 (aanmaak nieuwe melding) en dan bof (accepteren melding).
-- Voor PRIO-Hoog meldingen wordt MLD2BP gestuurd (if there is no handler), ongeacht deze settings
-- Sturing notificaties MLD2BO en MLD2B3 puur op basis van mld_disc_params_bonotify (Niet op de geconfigureerde WEB_MLDBO3 en WEB_MLDBOF rechten).
-- Notificaties: MLD2BO: Er is een nieuwe melding XXX.
-- MLD2B3: Voor melding XXX is uw acceptatie vereist.
-- | notificatie 1 | notificatie 2 |
-- BONOTIFY | (status Nieuw (2)) | (status Geaccepteerd (4)) | Te configureren WEB_MLDBO3 en WEB_MLDBOF rechten
-- 0 (niet) | X | X |
-- 1 (bof) | BOF(MLD2BO) | X | Alleen WEB_MLDBOF rechten zijn actief (niemand heeft WEB_MLDBO3 rechten).
-- 2 (bo3) | BO3(MLD2B3) | X | Zowel de WEB_MLDBO3 als WEB_MLDBOF rechten zijn actief.
-- 3 (bo3 en dan bof) | BO3(MLD2B3) | BOF(MLD2BO) | Zowel de WEB_MLDBO3 als WEB_MLDBOF rechten zijn actief.
BEGIN
SELECT DISTINCT m.mld_alg_locatie_key, -- DISTINCT omdat een melding met spoed zowel als speod als als new/acp kan voorkomen?
m.mld_alg_onroerendgoed_keys,
onrg.alg_type,
p.prs_afdeling_key,
CASE
WHEN pdisc_level = 1 THEN stdm.mld_ins_discipline_key
WHEN pdisc_level = 2 THEN m.mld_ins_discipline_key
END,
m.mld_melding_spoed,
mdp.mld_disc_params_bonotify,
mdp.mld_disc_params_bhgnotify,
mdp.mld_disc_params_offhours,
m.mld_melding_status,
m.mld_melding_behandelaar2_key
INTO lloc_key,
lonrg_key,
lalg_type,
lafd_key,
ldisc_key,
lspoed,
lbonotify,
lbhgnotify,
lnotifyooh,
lstatus,
lbehandelaar
FROM mld_melding m,
prs_perslid p,
mld_stdmelding stdm,
mld_disc_params mdp,
alg_v_onroerendgoed onrg
WHERE m.prs_perslid_key = p.prs_perslid_key AND stdm.mld_stdmelding_key = m.mld_stdmelding_key
-- Eerste notificatie: Melding is nieuw (2).
-- Naar BOF de MLD2BO notificatie: Alleen als bonotify = 1.
-- Naar BO3 de MLD2B3 notificatie: Alleen als bonotify = 2 en 3.
-- Tevens MLD2BP naar BOF indien het een spoed is and no handler is present
-- Tweede notificatie: Melding is net geaccepteerd (4).
-- Naar BOF de MLD2BO notificatie: Alleen als bonotify = 3.
--
AND ( (pdisc_level = 1 -- -- -- -- -- -- -- -- --
AND ((mld_melding_status = 2 OR mld_melding_status IS NULL) -- --
AND pcode != 'MLDACP' -- --
AND mdp.mld_disc_params_bonotify > 0) -- > MLD2BO || MLD2B3 --
OR (mld_melding_status = 4 -- --
AND pcode = 'MLDACP' -- --
AND mdp.mld_disc_params_bonotify = 3)) -- -- -- -- -- -- -- -- --
OR (pdisc_level = 2 -- --
AND (mld_melding_status = 2 OR mld_melding_status = 4) -- > MLDBHG --
AND mdp.mld_disc_params_bhgnotify > 0) -- --
OR mld_melding_spoed <= 2) -- -- -- -- -- -- -- -- --
AND ( (pdisc_level = 1 AND stdm.mld_ins_discipline_key = mdp.mld_ins_discipline_key)
OR (pdisc_level = 2 AND m.mld_ins_discipline_key = mdp.mld_ins_discipline_key))
AND m.mld_alg_onroerendgoed_keys = onrg.alg_onroerendgoed_keys(+)
AND mld_melding_key = pmeldingkey; -- op dit moment nog alleen voor NIEUWE meldingen
DBMS_OUTPUT.put_line ('melding zegt: hier moet genotificeerd worden');
-- These notifications are now sent on behalf of the system, what might be the local FM organisation
SELECT MAX (COALESCE(cd.ins_discipline_email, l.alg_locatie_email)) email
INTO lsender
FROM mld_melding m,
mld_stdmelding sm,
mld_discipline cd,
alg_locatie l
WHERE m.mld_stdmelding_key = sm.mld_stdmelding_key
AND sm.mld_ins_discipline_key = cd.ins_discipline_key
AND m.mld_alg_locatie_key = l.alg_locatie_key(+)
AND m.mld_melding_key = pmeldingkey;
-- Als die melding/status er niet is, is er niks te doen en sprongen we al naar de exception
-- Als die melding/status er wel is, gaan we verder
SELECT lcl.x ('fac_srtnotificatie_oms', fac_srtnotificatie_key, fac_srtnotificatie_oms),
fac_srtnotificatie_mode
INTO loms2bo, l2bomode
FROM fac_srtnotificatie
WHERE fac_srtnotificatie_code = 'MLD2BO';
SELECT lcl.x ('fac_srtnotificatie_oms', fac_srtnotificatie_key, fac_srtnotificatie_oms),
fac_srtnotificatie_mode
INTO loms2b3, l2b3mode
FROM fac_srtnotificatie
WHERE fac_srtnotificatie_code = 'MLD2B3';
SELECT lcl.x ('fac_srtnotificatie_oms', fac_srtnotificatie_key, fac_srtnotificatie_oms),
fac_srtnotificatie_mode
INTO lomsbhg, lbhgmode
FROM fac_srtnotificatie
WHERE fac_srtnotificatie_code = 'MLDBHG';
-- Vertaal melding-spoed (1-4) met 3=normaal naar email-spoed (1-3), waarbij 1=hoog, 2=normaal, 3=laag
IF lspoed <= 2
THEN
lnotiprio := 1;
ELSIF lspoed = 4
THEN
lnotiprio := 3;
ELSE
lnotiprio := 2;
END IF;
-- Igv spoed sturen we een extra-bericht (bedoeld als extra SMS) naar dezelfde BO-ers
-- als die overdag een bericht krijgen. De eventuele achterwacht is verondersteld zelf op te letten.
IF lnotiprio = 1 AND lbehandelaar IS NULL
THEN
BEGIN
DBMS_OUTPUT.put_line ('Spoedje!');
SELECT lcl.x ('fac_srtnotificatie_oms', fac_srtnotificatie_key, fac_srtnotificatie_oms),
fac_srtnotificatie_mode
INTO loms2bp, l2bpmode
FROM fac_srtnotificatie
WHERE fac_srtnotificatie_code = 'MLD2BP' AND fac_srtnotificatie_mode > 0;
priobericht := mld.mldsprintf (loms2bp, pmeldingkey);
EXCEPTION
WHEN NO_DATA_FOUND
THEN
priobericht := NULL;
l2bpmode := 0;
END;
DBMS_OUTPUT.put_line ('Wordt evt genotificeerd met mode '||l2bpmode);
END IF;
-- Deze gaat alleen naar de prio mail van het behandelteam en valt dus buiten de aankomende if/else tak die naar alle BO'ers stuurt
IF pdisc_level = 2 AND pcode = 'MLDBHG' AND BITAND(lbhgnotify, 2) = 2
THEN
mld.notifyprio (pmeldingkey, lspoed, NULL, 2);
END IF;
-- Met alle varianten op mode 0 (dat is hier niet ongebruikelijk) zijn deze notificaties
-- feitelijk uitgeschakeld en hoef ik dus ook niet duur te bepalen naar wie een notificatie niet gestuurd hoeft
-- Sturing notificatie MLDBHG, MLD2BO of MLD2B3 (evt aangevuld met MLD2BP)
IF (lbhgmode > 0 OR l2bpmode > 0) AND pcode = 'MLDBHG' AND BITAND(lbhgnotify, 1) = 1 AND (lstatus = 2 OR lstatus = 4)
THEN
lfunctiecode := 'WEB_MLDBOF';
lsrtnoticode := 'MLDBHG';
bericht := mld.mldsprintf (lomsbhg, pmeldingkey); -- de variabelen invullen
ELSIF (l2b3mode > 0 OR l2bpmode > 0) AND lstatus = 2 AND pcode != 'MLDACP' AND pcode != 'MLDBHG' AND (lbonotify = 2 OR lbonotify = 3)
THEN
lfunctiecode := 'WEB_MLDBO3';
lsrtnoticode := 'MLD2B3';
bericht := mld.mldsprintf (loms2b3, pmeldingkey); -- de variabelen invullen
ELSIF ((l2bomode > 0 OR l2bpmode > 0) AND (lstatus = 2 AND pcode != 'MLDACP' AND pcode != 'MLDBHG' AND lbonotify = 1)
OR (lstatus = 4 AND pcode = 'MLDACP' AND lbonotify = 3))
THEN
lfunctiecode := 'WEB_MLDBOF';
lsrtnoticode := 'MLD2BO';
bericht := mld.mldsprintf (loms2bo, pmeldingkey); -- de variabelen invullen
ELSE
DBMS_OUTPUT.put_line ('vakgroep zegt: hier hoeft niks genotificeerd te worden');
RETURN;
END IF;
EXCEPTION
WHEN NO_DATA_FOUND
THEN
DBMS_OUTPUT.put_line ('melding zegt: hier hoeft niks (meer) genotificeerd te worden');
-- hoeven we helemaal niets te doen
RETURN;
END;
DBMS_OUTPUT.put_line ('we gaan ' || lsrtnoticode || ': ' || bericht || ' sturen aan ' || lfunctiecode);
DBMS_OUTPUT.put_line ('we gaan nu kijken wie dat zijn');
lnrreceivers := 0;
lreceivers := '';
-- Buiten kantooruren naar de achterwacht melden.
IF lnotifyooh = 1
THEN
IF ( (fac.iswerkdag (SYSDATE) = 0) -- weekend of vrije dag
OR (fac.iswerktijd = 0) -- buiten kantoortijd
)
THEN
DBMS_OUTPUT.put_line ('Naar de achterwacht!');
lreceivers := fac.getsetting ('nightly_mld2bo_emailaddress');
lnrreceivers := lnrreceivers + 1;
fac.putnotificationsrtprio (NULL,
NULL,
lsrtnoticode,
pmeldingkey,
bericht,
NULL,
lreceivers,
NULL,
NULL,
lnotiprio, -- 1,2,3
lsender);
RETURN; -- Dan doen we de rest van de gebruikers helemaal niet
END IF;
END IF;
-- Hier gaan we berichten sturen naar de BO-ers
FOR boer
IN (SELECT g.prs_perslid_key
FROM fac_v_webgebruiker g,
fac_functie f,
prs_perslid p,
prs_v_afdeling d
WHERE g.fac_functie_key = f.fac_functie_key
AND g.ins_discipline_key = ldisc_key
AND g.prs_perslid_key = p.prs_perslid_key
AND d.prs_afdeling_key = p.prs_afdeling_key
AND (g.fac_gebruiker_prs_level_write = -1
OR (g.fac_gebruiker_prs_level_write = 0
AND d.prs_bedrijf_key = (SELECT aa.prs_bedrijf_key
FROM prs_v_afdeling aa
WHERE aa.prs_afdeling_key = lafd_key))
OR (g.fac_gebruiker_prs_level_write > 0
AND p.prs_afdeling_key IN
(SELECT prs_afdeling_key
FROM prs_v_afdeling_familie a
WHERE a.prs_afdeling_elder_key IN
(SELECT aa.prs_afdeling_elder_key
FROM prs_v_afdeling_familie aa
WHERE aa.prs_afdeling_key = lafd_key
AND aa.niveau = g.fac_gebruiker_prs_level_write))))
-- in ASP: if (params.loc_key>0, hier is lloc_key dan NULL en gaat het ook goed)
-- Afhankelijk op welk niveau de plaatsselector is ingevuld moet hier op dat niveau gechecked worden.
AND (g.fac_gebruiker_alg_level_write = -1
OR (g.fac_gebruiker_alg_level_write < 9
AND (CASE
WHEN lalg_type IS NULL
AND lloc_key IN
(SELECT alg_locatie_key
FROM fac_v_my_locations
WHERE prs_perslid_key = p.prs_perslid_key
AND niveau = fac_gebruiker_alg_level_write)
THEN
1
WHEN lalg_type = 'G'
AND lonrg_key IN
(SELECT alg_gebouw_key
FROM fac_v_my_buildings
WHERE prs_perslid_key = p.prs_perslid_key
AND niveau = fac_gebruiker_alg_level_write)
THEN
1
WHEN lalg_type = 'V'
AND lonrg_key IN
(SELECT alg_verdieping_key
FROM fac_v_my_floors
WHERE prs_perslid_key = p.prs_perslid_key
AND niveau = fac_gebruiker_alg_level_write)
THEN
1
WHEN lalg_type = 'R'
AND lonrg_key IN
(SELECT alg_ruimte_key
FROM fac_v_my_rooms
WHERE prs_perslid_key = p.prs_perslid_key
AND niveau = fac_gebruiker_alg_level_write)
THEN
1
ELSE
0
END) = 1))
AND fac_functie_code = lfunctiecode)
LOOP
fac.putnotificationsrtprio (NULL,
boer.prs_perslid_key,
lsrtnoticode,
pmeldingkey,
bericht,
NULL,
NULL,
NULL,
NULL,
lnotiprio,
lsender);
DBMS_OUTPUT.put_line ('bo-er: ' || boer.prs_perslid_key);
-- Het kan zijn dat er ook een extra spoed bericht gestuurd moet worden
IF l2bpmode > 0
THEN
DBMS_OUTPUT.put_line ('Krijgt ook nog de prionotificatie');
fac.putnotificationsrtprio (NULL,
boer.prs_perslid_key,
'MLD2BP', -- lsrtnoticode
pmeldingkey,
priobericht,
NULL,
NULL,
NULL,
NULL,
1, -- spoed dus :-)
lsender);
END IF;
IF lnrreceivers = 0
THEN
SELECT prs_perslid_naam_friendly
INTO lreceivers
FROM prs_v_perslid_fullnames
WHERE prs_perslid_key = boer.prs_perslid_key;
ELSE
SELECT prs_perslid_naam_friendly
INTO lreceivers1
FROM prs_v_perslid_fullnames
WHERE prs_perslid_key = boer.prs_perslid_key;
lreceivers := lreceivers || ', ' || lreceivers1;
END IF;
lnrreceivers := lnrreceivers + 1;
END LOOP;
IF lnrreceivers = 0
THEN
DBMS_OUTPUT.put_line ('no receivers');
IF l2bpmode > 0
THEN
-- er was een urgente melding, notificatie gewenst en niemand is als BO geconfigureerd
-- dan hoeven we niks te doen, maar toch sturen we de beheerder dan een signaal
fac.putsystemnotification (priobericht, 3); -- mode 3 is portal en mail
DBMS_OUTPUT.put_line ('inform admin: ' || priobericht);
END IF;
END IF;
EXCEPTION
WHEN NO_DATA_FOUND
THEN
RETURN;
END;
END;
-- Notificatie meldingen per prioriteit
PROCEDURE notifyprio (pmeldingkey IN NUMBER, prio IN NUMBER, pperslid_key IN NUMBER, pdisc_level IN NUMBER DEFAULT 1)
AS
lnotiprio NUMBER (1);
lcode fac_srtnotificatie.fac_srtnotificatie_code%TYPE;
loms fac_srtnotificatie.fac_srtnotificatie_oms%TYPE;
lmode fac_srtnotificatie.fac_srtnotificatie_mode%TYPE;
bericht VARCHAR2 (4000); -- fac_srtnotificatie_oms%TYPE kan te kort zijn na substitutie
emailnw1 mld_disc_params.mld_disc_params_emailnw1%TYPE;
emailnw2 mld_disc_params.mld_disc_params_emailnw2%TYPE;
emailnw3 mld_disc_params.mld_disc_params_emailnw3%TYPE;
emailnw4 mld_disc_params.mld_disc_params_emailnw4%TYPE;
smsnw1 mld_disc_params.mld_disc_params_smsnw1%TYPE;
smsnw2 mld_disc_params.mld_disc_params_smsnw2%TYPE;
smsnw3 mld_disc_params.mld_disc_params_smsnw3%TYPE;
smsnw4 mld_disc_params.mld_disc_params_smsnw4%TYPE;
BEGIN
IF pmeldingkey IS NULL
THEN
RETURN;
END IF;
SELECT mp.mld_disc_params_emailnw1,
mp.mld_disc_params_emailnw2,
mp.mld_disc_params_emailnw3,
mp.mld_disc_params_emailnw4,
mp.mld_disc_params_smsnw1,
mp.mld_disc_params_smsnw2,
mp.mld_disc_params_smsnw3,
mp.mld_disc_params_smsnw4
INTO emailnw1,
emailnw2,
emailnw3,
emailnw4,
smsnw1,
smsnw2,
smsnw3,
smsnw4
FROM mld_melding m,
mld_stdmelding stdm,
mld_disc_params mp
WHERE stdm.mld_stdmelding_key = m.mld_stdmelding_key
AND mp.mld_ins_discipline_key =
CASE
WHEN pdisc_level = 1 THEN stdm.mld_ins_discipline_key
WHEN pdisc_level = 2 THEN m.mld_ins_discipline_key
END
AND m.mld_melding_key = pmeldingkey;
-- Vertaal melding-spoed (1-4) met 3=normaal naar email-spoed (1-3), waarbij 1=hoog, 2=normaal, 3=laag
IF prio <= 2
THEN
lcode := 'MLD2BP';
lnotiprio := 1;
ELSE
lcode := 'MLDNW3';
lnotiprio := prio - 1;
END IF;
IF pdisc_level = 2
THEN
lcode := 'MLDBHG';
END IF;
SELECT lcl.x('fac_srtnotificatie_oms', fac_srtnotificatie_key, fac_srtnotificatie_oms),
fac_srtnotificatie_mode
INTO loms,
lmode
FROM fac_srtnotificatie
WHERE fac_srtnotificatie_code = lcode;
bericht := mld.mldsprintf (loms, pmeldingkey);
IF prio = 1 AND emailnw1 IS NOT NULL
THEN
fac.putnotificationsrtprio (pperslid_key,
NULL,
lcode,
pmeldingkey,
bericht,
lmode,
emailnw1,
smsnw1,
NULL,
lnotiprio,
NULL,
NULL);
ELSIF prio = 2 AND emailnw2 IS NOT NULL
THEN
fac.putnotificationsrtprio (pperslid_key,
NULL,
lcode,
pmeldingkey,
bericht,
lmode,
emailnw2,
smsnw2,
NULL,
lnotiprio,
NULL,
NULL);
ELSIF prio IN (3, 4) AND emailnw3 IS NOT NULL
THEN
fac.putnotificationsrtprio (pperslid_key,
NULL,
lcode,
pmeldingkey,
bericht,
lmode,
emailnw3,
smsnw3,
NULL,
lnotiprio,
NULL,
NULL);
ELSE
RETURN;
END IF;
END;
-- Stuur alle mogelijke opdracht goedkeurders een bericht als de opdracht status 10 heeft.
-- Naar wie, wordt reversed opgezocht op basis van toegekende autorisaties.
-- Lijkt heel erg sterk op bovenstaande notifybackoffice
PROCEDURE notifyopdrgoedkeurders (popdrkey IN NUMBER)
AS
lloc_key mld_melding.mld_alg_locatie_key%TYPE;
lafd_key prs_perslid.prs_afdeling_key%TYPE;
lmld_key mld_melding.mld_melding_key%TYPE;
lmld_opdr_disc_key mld_opdr.mld_opdr_discipline_key%TYPE;
lspoed mld_melding.mld_melding_spoed%TYPE;
loms fac_srtnotificatie.fac_srtnotificatie_oms%TYPE;
lopdr_approved mld_opdr.mld_opdr_approved%TYPE;
lopdr_kosten mld_opdr.mld_opdr_kosten%TYPE;
lbestellimiet mld_disc_params.mld_disc_params_bestellimiet%TYPE;
lbestellimiet2 mld_disc_params.mld_disc_params_bestellimiet2%TYPE;
lbestellimiet3 mld_disc_params.mld_disc_params_bestellimiet3%TYPE;
lbestellimiet4 mld_disc_params.mld_disc_params_bestellimiet4%TYPE;
lbestellimiet5 mld_disc_params.mld_disc_params_bestellimiet5%TYPE;
lgvs mld_typeopdr.mld_typeopdr_gvs%TYPE;
lrefiat mld_opdr.mld_statusopdr_key_refiat%TYPE;
lfunctiecode fac_functie.fac_functie_code%TYPE;
lsender mld_discipline.ins_discipline_email%TYPE;
bericht fac_srtnotificatie.fac_srtnotificatie_oms%TYPE; -- kan te kort zijn na substitutie
lnrreceivers NUMBER;
lreceivers fac_srtnotificatie.fac_srtnotificatie_oms%TYPE;
lreceivers1 fac_srtnotificatie.fac_srtnotificatie_oms%TYPE;
ltracking VARCHAR2(4000); -- moet tijdelijk groter dan fac_srtnotificatie.fac_srtnotificatie_oms%TYPE kunnen zijn
BEGIN
BEGIN
SELECT m.mld_alg_locatie_key,
p.prs_afdeling_key,
m.mld_melding_key,
o.mld_opdr_discipline_key,
m.mld_melding_spoed,
COALESCE(o.mld_opdr_approved, -1),
COALESCE(o.mld_opdr_kosten, 0),
COALESCE(mdp.mld_disc_params_bestellimiet, 0),
COALESCE(mdp.mld_disc_params_bestellimiet2, 0),
COALESCE(mdp.mld_disc_params_bestellimiet3, 0),
COALESCE(mdp.mld_disc_params_bestellimiet4, 0),
COALESCE(mdp.mld_disc_params_bestellimiet5, 0),
mto.mld_typeopdr_gvs,
COALESCE(o.mld_statusopdr_key_refiat, 0)
INTO lloc_key,
lafd_key,
lmld_key,
lmld_opdr_disc_key,
lspoed,
lopdr_approved,
lopdr_kosten,
lbestellimiet,
lbestellimiet2,
lbestellimiet3,
lbestellimiet4,
lbestellimiet5,
lgvs,
lrefiat
FROM mld_melding m,
prs_perslid p,
mld_opdr o,
mld_typeopdr mto,
mld_disc_params mdp
WHERE m.prs_perslid_key = p.prs_perslid_key
AND o.mld_opdr_discipline_key = mdp.mld_ins_discipline_key
AND o.mld_typeopdr_key = mto.mld_typeopdr_key
AND o.mld_statusopdr_key = 10
AND m.mld_melding_key = o.mld_melding_key
AND o.mld_opdr_key = popdrkey;
IF (lopdr_kosten <= lbestellimiet AND lopdr_kosten < lgvs) -- Dit eerst testen i.v.m. Ter goedkeuring. Verder moet sowieso goedgekeurd worden.
THEN
RETURN; -- Het bedrag is lager als de eerste limiet. De opdracht hoeft niet goed gekeurd te worden, dus een lege fiatteurs array teruggeven.
ELSIF (((fac.getsetting ('mld_opdr_approval_all') = 0 AND ((lopdr_kosten >= lbestellimiet) OR
(lopdr_kosten >= lgvs AND lopdr_approved < 0))) OR
(fac.getsetting ('mld_opdr_approval_all') = 1 AND lopdr_kosten <= lbestellimiet2)) AND
((lrefiat = 0 AND lopdr_approved <= lbestellimiet) OR -- Fiatteren volgens limieten.
(lrefiat > 0 AND lopdr_kosten >= lgvs AND lopdr_approved < 0))) -- Herfiatteren indien bedrag boven de GVS (lopdr_kosten >= lgvs) en het is de eerste goedkeuringsslag (lopdr_approved < 0).
THEN
lfunctiecode := 'WEB_ORDGOE';
ELSIF ((fac.getsetting ('mld_opdr_approval_all') = 0 AND lopdr_kosten >= lbestellimiet2 AND lopdr_approved = lbestellimiet2) OR
(fac.getsetting ('mld_opdr_approval_all') = 1 AND lopdr_kosten <= lbestellimiet3 AND ((lrefiat = 0 AND lopdr_approved <= lbestellimiet2) OR (lrefiat > 0 AND lopdr_kosten >= lgvs AND lopdr_approved < 0))))
THEN
lfunctiecode := 'WEB_ORDGO2';
ELSIF ((fac.getsetting ('mld_opdr_approval_all') = 0 AND lopdr_kosten >= lbestellimiet3 AND lopdr_approved = lbestellimiet3) OR
(fac.getsetting ('mld_opdr_approval_all') = 1 AND lopdr_kosten <= lbestellimiet4 AND ((lrefiat = 0 AND lopdr_approved <= lbestellimiet3) OR (lrefiat > 0 AND lopdr_kosten >= lgvs AND lopdr_approved < 0))))
THEN
lfunctiecode := 'WEB_ORDGO3';
ELSIF ((fac.getsetting ('mld_opdr_approval_all') = 0 AND lopdr_kosten >= lbestellimiet4 AND lopdr_approved = lbestellimiet4) OR
(fac.getsetting ('mld_opdr_approval_all') = 1 AND lopdr_kosten <= lbestellimiet5 AND ((lrefiat = 0 AND lopdr_approved <= lbestellimiet4) OR (lrefiat > 0 AND lopdr_kosten >= lgvs AND lopdr_approved < 0))))
THEN
lfunctiecode := 'WEB_ORDGO4';
ELSIF ((fac.getsetting ('mld_opdr_approval_all') = 0 AND lopdr_kosten >= lbestellimiet5 AND lopdr_approved >= lbestellimiet5) OR
(fac.getsetting ('mld_opdr_approval_all') = 1 AND lopdr_kosten > lbestellimiet5 AND ((lrefiat = 0 AND lopdr_approved <= lbestellimiet5) OR (lrefiat > 0 AND lopdr_kosten >= lgvs AND lopdr_approved < 0))))
THEN
lfunctiecode := 'WEB_ORDGO5';
ELSE
RETURN; -- Het goedgekeurde bedrag zit al boven de vijfde limiet. Geen approval meer nodig.
END IF;
-- These notifications are now sent on behalf of the system, what might be the local FM organisation
SELECT MAX (COALESCE(cd.ins_discipline_email, l.alg_locatie_email)) email
INTO lsender
FROM mld_opdr o,
mld_melding m,
mld_discipline cd,
alg_locatie l
WHERE o.mld_melding_key = m.mld_melding_key
AND cd.ins_discipline_key = lmld_opdr_disc_key
AND m.mld_alg_locatie_key = l.alg_locatie_key(+)
AND o.mld_opdr_key = popdrkey;
-- Als die er niet is sprongen we al naar de exception
-- Als die er wel is, gaan we verder
SELECT lcl.x('fac_srtnotificatie_oms', fac_srtnotificatie_key, fac_srtnotificatie_oms)
INTO loms
FROM fac_srtnotificatie
WHERE fac_srtnotificatie_code = 'ORD2GO'
AND fac_srtnotificatie_mode > 0;
-- Die laatste conditie is optimalisatie. Met code 0 is de notificatie feitelijk uitgeschakeld en
-- hoef ik dus ook niet duur te bepalen naar wie een notificatie niet gestuurd hoeft
-- Als deze niets oplevert gaan we dus ook weer naar de exception
-- Vertaal melding-spoed (1-4) naar email-spoed (1-3), 3=normaal
IF lspoed < 3
THEN
lspoed := 1;
ELSIF lspoed = 4
THEN
lspoed := 3;
ELSE
lspoed := 2;
END IF;
bericht := mld.opdrsprintf (loms, popdrkey); -- de variabelen invullen
lnrreceivers := 0;
lreceivers := '';
FOR boer
IN (SELECT g.prs_perslid_key
FROM fac_v_webgebruiker g,
fac_functie f,
prs_perslid p,
prs_v_afdeling d,
mld_melding m,
alg_v_allonroerendgoed onrg
WHERE g.fac_functie_key = f.fac_functie_key
AND g.prs_perslid_key = p.prs_perslid_key
AND d.prs_afdeling_key = p.prs_afdeling_key
AND g.ins_discipline_key = lmld_opdr_disc_key
AND m.mld_alg_onroerendgoed_keys = onrg.alg_onroerendgoed_keys(+)
AND m.mld_melding_key = lmld_key
AND (g.fac_gebruiker_prs_level_write = -1
OR (g.fac_gebruiker_prs_level_write = 0
AND d.prs_bedrijf_key = (SELECT aa.prs_bedrijf_key
FROM prs_v_afdeling aa
WHERE aa.prs_afdeling_key = lafd_key))
OR (g.fac_gebruiker_prs_level_write > 0
AND p.prs_afdeling_key IN
(SELECT prs_afdeling_key
FROM prs_v_afdeling_familie a
WHERE a.prs_afdeling_elder_key IN
(SELECT aa.prs_afdeling_elder_key
FROM prs_v_afdeling_familie aa
WHERE aa.prs_afdeling_key = lafd_key
AND aa.niveau = g.fac_gebruiker_prs_level_write))))
AND (g.fac_gebruiker_alg_level_write = -1
OR (g.fac_gebruiker_alg_level_write < 9
AND lloc_key IN
(SELECT alg_locatie_key
FROM fac_v_my_locations
WHERE prs_perslid_key = p.prs_perslid_key
AND niveau = fac_gebruiker_alg_level_write)))
AND (g.fac_gebruiker_alg_level_write = -1
OR (g.fac_gebruiker_alg_level_write < 9
AND (CASE
WHEN m.mld_alg_onroerendgoed_keys IS NULL
AND m.mld_alg_locatie_key IN (SELECT alg_locatie_key
FROM fac_v_my_locations
WHERE prs_perslid_key = p.prs_perslid_key
AND niveau = g.fac_gebruiker_alg_level_write)
THEN
1
WHEN onrg.alg_type = 'G'
AND m.mld_alg_onroerendgoed_keys IN (SELECT alg_gebouw_key
FROM fac_v_my_buildings
WHERE prs_perslid_key = p.prs_perslid_key
AND niveau = g.fac_gebruiker_alg_level_write)
THEN
1
WHEN onrg.alg_type = 'V'
AND m.mld_alg_onroerendgoed_keys IN (SELECT alg_verdieping_key
FROM fac_v_my_floors
WHERE prs_perslid_key = p.prs_perslid_key
AND niveau = g.fac_gebruiker_alg_level_write)
THEN
1
WHEN onrg.alg_type = 'R'
AND m.mld_alg_onroerendgoed_keys IN (SELECT alg_ruimte_key
FROM fac_v_my_rooms
WHERE prs_perslid_key = p.prs_perslid_key
AND niveau = g.fac_gebruiker_alg_level_write)
THEN
1
ELSE
0
END) = 1))
AND fac_functie_code = lfunctiecode)
LOOP
fac.putnotificationsrtprio (NULL,
boer.prs_perslid_key,
'ORD2GO',
popdrkey,
bericht,
NULL,
NULL,
NULL,
NULL,
lspoed, -- 1,2,3,4
lsender
);
IF lnrreceivers = 0 THEN
SELECT prs_perslid_naam_friendly
INTO lreceivers
FROM prs_v_perslid_fullnames
WHERE prs_perslid_key = boer.prs_perslid_key;
ELSE
SELECT prs_perslid_naam_friendly
INTO lreceivers1
FROM prs_v_perslid_fullnames
WHERE prs_perslid_key = boer.prs_perslid_key;
lreceivers := lreceivers||', '||lreceivers1;
END IF;
lnrreceivers := lnrreceivers+1;
END LOOP;
IF lnrreceivers > 0 THEN
DBMS_OUTPUT.PUT_LINE(lnrreceivers);
ltracking := lcl.l ('lcl_ord_notification_sent_to');
--ltracking := 'Notitificatie ''{0}'' verstuurd aan {1}';
DBMS_OUTPUT.PUT_LINE(ltracking);
ltracking := REPLACE (ltracking, '{0}', bericht);
ltracking := REPLACE (ltracking, '{1}', lreceivers);
DBMS_OUTPUT.PUT_LINE(ltracking);
fac.trackaction ('#ORDMAI', popdrkey, NULL, NULL, SUBSTR(ltracking,1,2048)); -- maxlengte van fac_srtnotificatie_oms
END IF;
EXCEPTION
WHEN NO_DATA_FOUND
THEN
RETURN;
END;
END;
FUNCTION mld_besteed_budget_pgb (p_prs_key IN NUMBER, p_disc_key IN NUMBER)
RETURN NUMBER
AS
l_budgetbesteld NUMBER := 0;
BEGIN
-- Besteed budget van meegegeven persoon dit jaar voor de meegegeven discipline i.v.m. Persoons Gebonden Budget (PGB).
-- Eventueel uitgezonderd (huidige) bestellingkey bes_key en meldingopdrachtkey opdr_key.
-- De discipline instelling disc_params_pgb moet 1 of 3 zijn. Afhankelijk van deze instelling roep je de pgb of agb versie aan. Hier opnieuw controleren is niet nodig.
-- Totaalbedrag van eerdere bestellingen en meldingopdrachten dit jaar van de besteller en behandelaar i.v.m. Persoons Gebonden Budget (PGB).
SELECT COALESCE(SUM(totaalbedrag), 0) budgetbesteld -- Korting en levkosten zijn 0.
INTO l_budgetbesteld
FROM (SELECT SUM (totaalbedrag) totaalbedrag
FROM (SELECT SUM (o.mld_opdr_kosten) totaalbedrag
, o.mld_opdr_key
FROM mld_opdr o
WHERE o.prs_perslid_key = p_prs_key
AND o.mld_opdr_discipline_key = p_disc_key
-- Alleen meldingopdrachten in de actieve opdracht fase (Uitgegeven(5) en Geaccepteerd(8)),
-- in de afhandelings fase (Technisch voltooid(6) en Kosten voltooid(9)) en in de gereed fase (Verwerkt(7)).
AND o.mld_statusopdr_key IN (5, 6, 7, 8, 9)
AND o.mld_opdr_datumbegin >= TRUNC (SYSDATE, 'YEAR')
GROUP BY o.mld_opdr_key) tot
, mld_opdr o
WHERE o.mld_opdr_key = tot.mld_opdr_key);
RETURN l_budgetbesteld;
END;
FUNCTION mld_besteed_budget_agb (p_kp_key IN NUMBER)
RETURN NUMBER
AS
l_budgetbesteld NUMBER := 0;
l_kp_limietperiode NUMBER (1);
l_periode VARCHAR2 (4);
BEGIN
-- Besteed budget van meegegeven persoon afgelopen periode i.v.m. Afdelings Gebonden Budget (AGB).
-- Eventueel uitgezonderd (huidige) bestellingkey bes_key en meldingopdrachtkey opdr_key.
-- De discipline instelling disc_params_pgb moet 1 of 3 zijn. Afhankelijk van deze instelling roep je de pgb of agb versie aan. Hier opnieuw controleren is niet nodig.
-- Totaalbedrag van eerdere bestellingen en meldingopdrachten van afgelopen periode van de besteller en behandeaar i.v.m. Afdelings Gebonden Budget (AGB).
-- Limietperiode kostenplaats (prs_kostenplaats_limietperiode): 0(of NULL)=geen(oneindig) (default), 1=maand, 2=jaar.
IF p_kp_key > 0
THEN
-- Er is een kostenplaats gevonden.
-- De limiet periode van de kostenplaatsgroep overruled die van de kostenplaats indien ingevuld.
SELECT CASE COALESCE(kg.prs_kostenplaatsgrp_limperiode, 0) -- Indien kostenplaats geen kostenplaatsgroep heeft dan ook "Geen" en eigen limietperiode van de kostenplaats nemen.
WHEN 0 -- Geen.
THEN k.prs_kostenplaats_limietperiode
ELSE kg.prs_kostenplaatsgrp_limperiode -- Maand of Jaar.
END limietperiode
INTO l_kp_limietperiode
FROM prs_kostenplaats k
, prs_kostenplaatsgrp kg
WHERE k.prs_kostenplaatsgrp_key = kg.prs_kostenplaatsgrp_key(+)
AND k.prs_kostenplaats_key = p_kp_key;
IF l_kp_limietperiode = 1
THEN
l_periode := 'MM'; -- Maandelijks budget.
ELSIF l_kp_limietperiode = 2
THEN
l_periode := 'YYYY'; -- Jaarlijks budget.
ELSE
l_periode := NULL;
END IF;
SELECT COALESCE(SUM(totaalbedrag), 0) budgetbesteld -- Korting en levkosten zijn 0.
INTO l_budgetbesteld
FROM (SELECT SUM (totaalbedrag) totaalbedrag
FROM (SELECT SUM (o.mld_opdr_kosten) totaalbedrag
, o.mld_opdr_key
FROM mld_opdr o
, mld_disc_params mdp
WHERE o.mld_opdr_discipline_key = mdp.mld_ins_discipline_key
AND mdp.mld_disc_params_pgb IN (2,3) -- Alleenn agb meetellen: 2 = Alleen agb, 3 = Beiden, pgb en agb.
AND o.prs_kostenplaats_key = p_kp_key
-- Alleen meldingopdrachten in de actieve opdracht fase (Uitgegeven(5) en Geaccepteerd(8)),
-- in de afhandelings fase (Technisch voltooid(6) en Kosten voltooid(9)) en in de gereed fase (Verwerkt(7)).
AND o.mld_statusopdr_key IN (5, 6, 7, 8, 9)
AND ((l_periode IS NOT NULL AND o.mld_opdr_datumbegin >= TRUNC (SYSDATE, l_periode)) -- De eerste van de deze maand of 1 januari dit jaar
OR (l_periode IS NULL))
GROUP BY o.mld_opdr_key) tot
, mld_opdr o
WHERE o.mld_opdr_key = tot.mld_opdr_key);
END IF;
RETURN l_budgetbesteld;
END;
PROCEDURE mld_addautoorder (p_melding_key IN NUMBER)
AS
l_autoorder mld_stdmelding.mld_stdmelding_autoorder%TYPE;
l_prs_perslid_key prs_perslid.prs_perslid_key%TYPE;
l_mld_stdmelding_key mld_stdmelding.mld_stdmelding_key%TYPE;
l_mld_disc_params_opdr_kosten NUMBER;
l_mld_stdmelding_autoorderamnt mld_stdmelding.mld_stdmelding_autoorderamount%TYPE;
l_mld_disc_params_pgb mld_disc_params.mld_disc_params_pgb%TYPE;
l_prs_kostenplaats_key prs_kostenplaats.prs_kostenplaats_key%TYPE;
l_prs_kostensoort_key prs_kostensoort.prs_kostensoort_key%TYPE;
l_ins_discipline_key mld_stdmelding.mld_ins_discipline_key%TYPE;
l_bhg_discipline_key mld_melding.mld_ins_discipline_key%TYPE;
l_opdr_discipline_key mld_opdr.mld_opdr_discipline_key%TYPE;
l_mld_melding_einddatum mld_melding.mld_melding_einddatum%TYPE;
l_mld_stdmelding_enddate_empty mld_stdmelding.mld_stdmelding_enddate_empty%TYPE;
l_mld_melding_omschrijving mld_melding.mld_melding_omschrijving%TYPE;
l_mld_melding_onderwerp mld_melding.mld_melding_onderwerp%TYPE;
l_prs_kostenplaats_fiat prs_kostenplaats.prs_kostenplaats_fiat%TYPE;
l_mld_disc_params_bestellimiet mld_disc_params.mld_disc_params_bestellimiet%TYPE;
l_mld_typeopdr_key mld_typeopdr.mld_typeopdr_key%TYPE;
l_for_approval BOOLEAN;
l_mld_typeopdr_fvs mld_typeopdr.mld_typeopdr_fvs%TYPE;
l_mld_typeopdr_gvs mld_typeopdr.mld_typeopdr_gvs%TYPE;
l_mld_typeopdr_isofferte mld_typeopdr.mld_typeopdr_isofferte%TYPE;
l_mld_typeopdr_kosten mld_typeopdr.mld_typeopdr_kosten%TYPE;
l_mld_typeopdr_kst_verplicht NUMBER;
l_mld_typeopdr_slamode mld_typeopdr.mld_typeopdr_slamode%TYPE;
l_exceeds_pgb BOOLEAN;
l_exceeds_agb BOOLEAN;
l_mld_adres_key mld_melding.mld_adres_key%TYPE;
l_mld_alg_onroerendgoed_keys mld_melding.mld_alg_onroerendgoed_keys%TYPE;
l_mld_alg_locatie_key mld_melding.mld_alg_locatie_key%TYPE;
l_alg_gebouw_key alg_v_allonrgoed_gegevens.alg_gebouw_key%TYPE;
l_alg_verdieping_key alg_v_allonrgoed_gegevens.alg_verdieping_key %TYPE;
l_alg_ruimte_key alg_v_allonrgoed_gegevens.alg_ruimte_key%TYPE;
l_prs_dienst_key NUMBER;
l_prs_bedrijf_key prs_v_aanwezigbedrijf.prs_bedrijf_key%TYPE;
l_aantal NUMBER;
l_bdl_tijdsduur prs_bedrijfdienstlocatie.prs_bdl_t_uitvoertijd.tijdsduur%TYPE;
l_bdl_eenheid prs_bedrijfdienstlocatie.prs_bdl_t_uitvoertijd.eenheid%TYPE;
l_prs_bedrijf_uurloon prs_bedrijf.prs_bedrijf_uurloon%TYPE;
l_mld_opdr_einddatum mld_opdr.mld_opdr_einddatum%TYPE;
l_mld_opdr_omschrijving mld_opdr.mld_opdr_omschrijving%TYPE;
l_prs_bedrijfadres_url prs_bedrijfadres.prs_bedrijfadres_url%TYPE;
l_haswrite NUMBER (1);
l_new_opdr_key NUMBER (10);
l_approver_key NUMBER (10);
l_action VARCHAR2 (6);
BEGIN
BEGIN
SELECT sm.mld_stdmelding_autoorder
, m.prs_perslid_key
, sm.mld_stdmelding_key
, mdp.mld_disc_params_opdr_kosten
, sm.mld_stdmelding_autoorderamount
, mdp.mld_disc_params_pgb
, m.prs_kostenplaats_key
, sm.prs_kostensoort_key
, sm.mld_ins_discipline_key
, m.mld_ins_discipline_key
, m.mld_melding_einddatum
, sm.mld_stdmelding_enddate_empty
, m.mld_melding_omschrijving
, m.mld_melding_onderwerp
, k.prs_kostenplaats_fiat
, sm.prs_dienst_key
, mdp.mld_disc_params_bestellimiet
INTO l_autoorder
, l_prs_perslid_key
, l_mld_stdmelding_key
, l_mld_disc_params_opdr_kosten
, l_mld_stdmelding_autoorderamnt
, l_mld_disc_params_pgb
, l_prs_kostenplaats_key
, l_prs_kostensoort_key
, l_ins_discipline_key
, l_bhg_discipline_key
, l_mld_melding_einddatum
, l_mld_stdmelding_enddate_empty
, l_mld_melding_omschrijving
, l_mld_melding_onderwerp
, l_prs_kostenplaats_fiat
, l_prs_dienst_key
, l_mld_disc_params_bestellimiet
FROM mld_melding m
, mld_stdmelding sm
, ins_tab_discipline d
, mld_disc_params mdp
, prs_kostenplaats k
WHERE m.mld_stdmelding_key = sm.mld_stdmelding_key
AND sm.mld_ins_discipline_key = d.ins_discipline_key
AND d.ins_discipline_key = mdp.mld_ins_discipline_key
AND m.prs_kostenplaats_key = k.prs_kostenplaats_key(+)
AND m.mld_melding_key = p_melding_key;
EXCEPTION
WHEN NO_DATA_FOUND
THEN
-- Internal error; mld_melding must exist.
RETURN;
END;
IF fac.getsetting('mld_opdr_discipline_mode') = '1'
THEN
l_opdr_discipline_key := l_ins_discipline_key;
ELSE
l_opdr_discipline_key := COALESCE(l_bhg_discipline_key, l_ins_discipline_key);
END IF;
-- Moet er bij deze melding automatisch een opdracht worden aangemaakt?
IF l_autoorder = 0
THEN
-- No, done.
RETURN;
END IF;
-- De behandelaar is initieel diegene die de opdracht aanmaakt (user). Hier nemen we dezelfde persoon als bij de (workflow) melding.
-- Deze persoon moet wel MLDBOF en/of MLDBO3 schrijfrechten hebben omdat we anders niet kunnen bepalen of goedgekeurd of gefiatteerd moet worden.
-- Als deze persoon geen MLDBOF en/of MLDBO3 schrijfrechten heeft dan maken we wel een opdracht aan, maar dan wordt hij niet als behandelaar ingevuld.
SELECT CASE
WHEN COALESCE(MIN(fac_gebruiker_prs_level_write), 9) < 9 OR COALESCE(MIN(fac_gebruiker_alg_level_write), 9) < 9
THEN 1
ELSE 0
END
INTO l_haswrite
FROM fac_v_webgebruiker w,
fac_functie f
WHERE w.fac_functie_key = f.fac_functie_key
AND w.prs_perslid_key = l_prs_perslid_key
AND f.fac_functie_code IN ('WEB_MLDBOF', 'WEB_MLDBO3')
AND ((l_ins_discipline_key IS NOT NULL AND ins_discipline_key = l_ins_discipline_key)
OR l_ins_discipline_key IS NULL);
BEGIN
-- Bij automatische opdrachten pakken we per definitie de default opdracht type. We eisen dat die is ingevuld.
SELECT sm.mld_typeopdr_key
, mto.mld_typeopdr_fvs
, mto.mld_typeopdr_gvs
, mto.mld_typeopdr_isofferte
, mld_typeopdr_kosten
, mld_typeopdr_kosten_verplicht
, mld_typeopdr_slamode
INTO l_mld_typeopdr_key
, l_mld_typeopdr_fvs
, l_mld_typeopdr_gvs
, l_mld_typeopdr_isofferte
, l_mld_typeopdr_kosten
, l_mld_typeopdr_kst_verplicht
, l_mld_typeopdr_slamode
FROM mld_stdmelding sm
, mld_typeopdr mto
WHERE sm.mld_typeopdr_key = mto.mld_typeopdr_key
AND sm.mld_typeopdr_key IS NOT NULL
AND sm.mld_stdmelding_key = l_mld_stdmelding_key;
EXCEPTION
WHEN NO_DATA_FOUND
THEN
-- Internal error; mld_typeopdr_key must exist.
RETURN;
END;
IF l_mld_typeopdr_fvs IS NULL
THEN
l_mld_typeopdr_fvs := 0;
END IF;
-- Moet er gefiatteerd worden?
IF l_mld_stdmelding_autoorderamnt < l_mld_typeopdr_fvs
THEN
l_for_approval := FALSE;
ELSIF l_mld_disc_params_pgb > 0
THEN
-- Persoonlijk Gebonden Budget (PGB) en Afdeling Gebonden Budget (AGB) controle
-- Fiatteringsproces moet gevolgd worden op de naam van de user
-- var exceeds_pgb = mld.exceeds_pgb(tot_kosten, user_key, disc_key)
l_exceeds_pgb := fac.exceeds_pgb(l_mld_stdmelding_autoorderamnt, l_prs_perslid_key, l_opdr_discipline_key, l_mld_disc_params_pgb);
l_exceeds_agb := fac.exceeds_agb(l_mld_stdmelding_autoorderamnt, COALESCE(l_prs_kostenplaats_key, -1), l_opdr_discipline_key, l_mld_disc_params_pgb);
IF l_exceeds_pgb OR l_exceeds_agb
THEN
-- Voor melding opdrachten heb je altijd BO rechten nodig.
-- Een opdracht kan dus nooit van een FE komen. Aan de setting "mld_pgb_fe_fiat" (zoals bes_pgb_fe_fiat) heb je hier dan niets.
IF fac.getsetting('mld_pgb_fiattering') = 1
THEN
-- Algemene fiatterings proces noodzakelijk naast PGB fiatering.
l_for_approval := TRUE;
ELSE
-- Fiatteringsproces moet gevolgd worden op de naam van de user.
-- Persoonlijk Gebonden Budget (PGB) en/of Afdeling Gebonden Budget (AGB) wordt overschreden.
-- Opdracht kan dus niet aangemaakt worden.
RETURN;
END IF;
END IF;
-- Wel even checken of er een fiatteur gevonden kan worden.
IF l_for_approval OR
(fac.getsetting('mld_use_order_approval') = 1 AND
l_mld_stdmelding_autoorderamnt > 0 AND
(l_mld_stdmelding_autoorderamnt > fac.getsetting('can_selfapprove'))) -- Ik kan niet zelf fiatteren of kosten overschrijden het profiel.
THEN
l_for_approval := TRUE;
-- Wie moet op verzoek goedkeuren voor deze kostenplaats, terwijl het bedrag wellicht onbekend is?
-- Eerste fiatteur (pkey) mag niet fiatteren want het zit boven zijn profiel limiet.
-- Alleen de melder van de melding mag niet zelf goedkeuren boven het bedrag can_selfapprove.
-- Bij een kpg fiatteur moeten we de volgende hebben en niet de laatste, daarom (fiatbedrag >= 0) meegeven.
-- prs.getfiatteur (pkostenplaats_key, pexcludekey, pondergrens, pdisckey, pfiatbedrag)
SELECT prs.getfiatteur (COALESCE(l_prs_kostenplaats_key, -1), -1, l_mld_stdmelding_autoorderamnt, l_opdr_discipline_key, 0)
INTO l_approver_key
FROM DUAL;
END IF;
ELSE
-- Standaard fiatteringscontrole
-- De opdrachtaanmaker, Melder van de melding/BO-medewerker, contactpersoon enz, zijn allemaal de gelijk, namelijk de meldingaanmaker.
IF (fac.getsetting('mld_use_order_approval') = 1 AND
l_mld_stdmelding_autoorderamnt > 0 AND
(l_mld_stdmelding_autoorderamnt > fac.getsetting('can_selfapprove') OR
fac.exceeds_profiel(l_mld_stdmelding_autoorderamnt, l_prs_perslid_key, l_opdr_discipline_key))) -- Ik kan niet zelf fiatteren of kosten overschrijden het profiel.
THEN
l_for_approval := TRUE;
-- prs.getfiatteur (pkostenplaats_key, pexcludekey, pondergrens, pdisckey, pfiatbedrag)
SELECT prs.getfiatteur (COALESCE(l_prs_kostenplaats_key, -1), -1, l_mld_stdmelding_autoorderamnt, l_opdr_discipline_key, 0)
INTO l_approver_key
FROM DUAL;
END IF;
END IF;
IF l_for_approval AND l_prs_kostenplaats_fiat = 1
THEN
IF l_approver_key = -1
THEN
-- Internal error; approver must exist.
RETURN;
--ELSE
-- Er is nu een altijd een eerste approver_key gevonden (met of zonder voldoende fiatteringsrechten). Anders al een abort.
-- approver_key is oke of indien -1 dan is er geen approval meer nodig (is al geabort hierboven anders)
END IF;
END IF;
-- Zetten van de status van de melding naar geaccepteerd en afhandelen van de tracking.
mld.setmeldingstatus(p_melding_key, 4, NULL, 1);
-- (re)calculate the conditionscores of the releated objects
IF fac.getsetting('cnd_gebreken_srtdisc_key') > 0
THEN
cnd.process_mjb_score_effects(p_melding_key, NULL);
END IF;
-- Voor automatische opdrachten controleren of uitvoerende bepaald kan worden (niet voor offertes).
IF l_mld_typeopdr_isofferte = 0
THEN
-- Daarvoor zijn plaatsgegevens relevant.
-- Eerst kijken of er een locatie key bepaald kan worden.
BEGIN
SELECT mld_alg_locatie_key
, mld_adres_key
, mld_alg_onroerendgoed_keys
INTO l_mld_alg_locatie_key
, l_mld_adres_key
, l_mld_alg_onroerendgoed_keys
FROM mld_melding
WHERE mld_melding_key = p_melding_key
AND (mld_alg_locatie_key IS NOT NULL OR mld_adres_key IS NOT NULL);
EXCEPTION
WHEN NO_DATA_FOUND
THEN -- Geen locatie of adres
l_mld_alg_locatie_key := NULL;
l_mld_adres_key := NULL;
l_mld_alg_onroerendgoed_keys := NULL;
END;
IF l_mld_alg_locatie_key IS NULL AND l_mld_adres_key IS NOT NULL
THEN
-- Als we geen locatiekey hebben maar wel een afleveradres, kunnen we mogelijk ook een locatiekey bepalen.
SELECT alg_locatie_key
INTO l_mld_alg_locatie_key
FROM mld_adres
WHERE mld_adres_key = l_mld_adres_key;
END IF;
IF l_mld_alg_onroerendgoed_keys > 0
THEN
SELECT g.alg_gebouw_key
, g.alg_verdieping_key
, g.alg_ruimte_key
INTO l_alg_gebouw_key
, l_alg_verdieping_key
, l_alg_ruimte_key
FROM alg_v_allonrgoed_gegevens g
WHERE g.alg_onroerendgoed_keys = l_mld_alg_onroerendgoed_keys;
END IF;
-- Dienst controle is bij het aanmaken van de start melding al gedaan.
-- Voor de opdracht wordt namelijk uit gegaan van dezelfde mld_stdmelding, mld_alg_onroerendgoed_keys (locatie, gebouw en ruimte) en prs_perslid_voor.
-- De controle zal dan dus hetzelfde zijn.
-- Dienst controle: stdmelding -> prs_dienst_key -> prs_bedrijf_key.
-- Controles:
-- 1) Er moet een bedrijf bij de dienst gevonden kunnen worden.
-- 2) Als de melding onderdeel is van *een* dienstniveau dan moet bij de ruimte
-- een niveau ingevuld zijn waar deze melding onderdeel van is.
-- 3) Als bij de melding is aangegeven dat hij alleen voor de eigen organisatie mag dan
-- moet die ruimte (via PRS_RUIMTEAFDELING) gehuurd worden door "eigen" afdeling
-- "eigen" is gedefinieerd als een afdeling die ons als parent heeft
-- of een afdeling die een parent van ons is.
-- De controles kunnen hier overgeslagen worden en kan de prs bedrijf_key direct bepalen.
IF l_prs_dienst_key IS NOT NULL
THEN
-- Controleer of er <20><>n bedrijf is dat deze dienst levert (op deze locatie/dit gebouw)
IF l_alg_gebouw_key IS NOT NULL
THEN
SELECT MIN(bdl.prs_bedrijf_key) prs_bedrijf_key
, COUNT(DISTINCT bdl.prs_bedrijf_key) aantal
, MIN(bdl.prs_bdl_t_uitvoertijd.tijdsduur) tijdsduur
, MIN(bdl.prs_bdl_t_uitvoertijd.eenheid) eenheid
INTO l_prs_bedrijf_key
, l_aantal
, l_bdl_tijdsduur
, l_bdl_eenheid
FROM prs_bedrijfdienstlocatie bdl
, prs_v_aanwezigbedrijf b
WHERE bdl.prs_bedrijf_key = b.prs_bedrijf_key
AND bdl.prs_dienst_key = l_prs_dienst_key
AND ((bdl.alg_gebouw_key = l_alg_gebouw_key
OR bdl.alg_gebouw_key IS NULL)
AND (bdl.alg_locatie_key = l_mld_alg_locatie_key
OR bdl.alg_locatie_key IS NULL));
ELSIF l_mld_alg_locatie_key IS NOT NULL
THEN
SELECT MIN(bdl.prs_bedrijf_key) prs_bedrijf_key
, COUNT(DISTINCT bdl.prs_bedrijf_key) aantal
, MIN(bdl.prs_bdl_t_uitvoertijd.tijdsduur)
, MIN(bdl.prs_bdl_t_uitvoertijd.eenheid) eenheid
INTO l_prs_bedrijf_key
, l_aantal
, l_bdl_tijdsduur
, l_bdl_eenheid
FROM prs_bedrijfdienstlocatie bdl
, prs_v_aanwezigbedrijf b
WHERE bdl.prs_bedrijf_key = b.prs_bedrijf_key
AND bdl.prs_dienst_key = l_prs_dienst_key
AND (bdl.alg_locatie_key = l_mld_alg_locatie_key
OR bdl.alg_locatie_key IS NULL);
ELSE
SELECT MIN(bdl.prs_bedrijf_key) prs_bedrijf_key
, COUNT(DISTINCT bdl.prs_bedrijf_key) aantal
, MIN(bdl.prs_bdl_t_uitvoertijd.tijdsduur) tijdsduur
, MIN(bdl.prs_bdl_t_uitvoertijd.eenheid) eenheid
INTO l_prs_bedrijf_key
, l_aantal
, l_bdl_tijdsduur
, l_bdl_eenheid
FROM prs_bedrijfdienstlocatie bdl
, prs_v_aanwezigbedrijf b
WHERE bdl.prs_bedrijf_key = b.prs_bedrijf_key
AND bdl.prs_dienst_key = l_prs_dienst_key
AND bdl.alg_gebouw_key IS NULL
AND bdl.alg_locatie_key IS NULL; -- Bestaat er dan misschien maar 1 bedrijf voor deze dienst zonder loc/geb scope ?
END IF;
-- Indien dienst vereist en aantal is 0, dan is de dienst niet beschikbaar voor deze locatie/dit gebouw.
-- Indien aantal groter is dan 0, dan kan ik geen goede keuze maken.
IF l_aantal <> 1
THEN
l_prs_bedrijf_key := NULL;
END IF;
END IF;
IF l_prs_bedrijf_key IS NULL
THEN
-- Internal error; prs_bedrijf_key must exist.
RETURN;
END IF;
END IF;
-- Zijn de totale kosten verplicht en ingevuld? Hier gaat het om een nieuwe opdracht en moet dus gecontroleerd worden.
-- Opdrachttype: mld_typeopdr_kosten_verplicht (typeopdr kosten): 0 = Niet verplicht, 1 = Save + 2 = Afmelden, 4 = Afronden.
-- Vakgroep: mld_disc_params_opdr_kosten (opdracht kosten): 0 = Niet verplicht, 7 = Aanmaak, 6 = Afmelden, 4 = Afronden.
-- Nieuwe opdracht, dus ik hoef alleen te kijken naar Save (mld_typeopdr_kosten_verplicht) en Aanmaak (mld_disc_params_opdr_kosten).
IF ((BITAND(l_mld_typeopdr_kst_verplicht, 1) = 1
OR (l_mld_typeopdr_kst_verplicht = 0 AND BITAND(l_mld_disc_params_opdr_kosten, 1) = 1)) -- Zijn de kosten verplicht voor nieuwe opdracht?
AND l_mld_stdmelding_autoorderamnt IS NULL) -- Totale kosten bij autoorder.
THEN
-- Internal error; The costs must be filled in.
RETURN;
END IF;
-- Als kosten meegerekend moeten worden ("Kosten meerekenen") dan moet er wel een kostenplaats bekend zijn.
IF l_mld_typeopdr_kosten = 1 AND l_prs_kostenplaats_key IS NULL -- Kosten meerekenen?
THEN
-- Internal error; prs_kostenplaats_key must exist.
RETURN;
END IF;
-- Combinatievalidatie
IF l_prs_kostenplaats_key IS NOT NULL AND NOT prs.combinatievalidatie(l_prs_kostenplaats_key, l_prs_kostensoort_key, l_opdr_discipline_key)
THEN
-- Internal error; Combinatievalidatie: Dit product is niet toegestaan voor deze kostenplaats.
RETURN;
END IF;
-- mld_c_mld_uitvoerende_keys
IF l_prs_bedrijf_key IS NULL
THEN
-- Internal error; prs_bedrijf_key must exist.
RETURN;
END IF;
-- Uurloon
SELECT b.prs_bedrijf_uurloon
INTO l_prs_bedrijf_uurloon
FROM prs_bedrijf b
WHERE b.prs_bedrijf_key = l_prs_bedrijf_key; -- Er is een geldige uitvoerder.
-- Einddatum bepalen
IF l_mld_typeopdr_slamode = 1
THEN
-- Uitvoertijd opdracht is bedrijf uitvoertijd.
-- Als er een specifieke uitvoertijd voor ons gebouw is, dan zijn l_bdl_tijdsduur en l_bdl_eenheid hiermee gevuld.
IF l_bdl_tijdsduur IS NULL
THEN
SELECT b.prs_bedrijf_t_uitvoertijd.tijdsduur
, b.prs_bedrijf_t_uitvoertijd.eenheid
INTO l_bdl_tijdsduur
, l_bdl_eenheid
FROM prs_bedrijf b
WHERE b.prs_bedrijf_key = l_prs_bedrijf_key; -- Er is een geldige uitvoerder.
END IF;
ELSIF l_mld_typeopdr_slamode = 2
THEN
-- Uitvoertijd opdracht is melding uitvoertijd.
SELECT m.mld_melding_t_uitvoertijd.tijdsduur
, m.mld_melding_t_uitvoertijd.eenheid
INTO l_bdl_tijdsduur
, l_bdl_eenheid
FROM mld_melding m
WHERE m.mld_melding_key = p_melding_key;
-- ELSE l_mld_typeopdr_slamode = 3
-- Dan blijft tijdsduur en eenheid NULL en wordt uiteindelijk de einddatum opdracht gelijk aan de einddatum melding.
END IF;
IF l_bdl_tijdsduur IS NOT NULL
THEN
-- Bepaal/Bereken de SLA-einddatum.
IF l_mld_stdmelding_enddate_empty = 1
THEN
l_mld_opdr_einddatum := NULL;
ELSE
-- l_bdl_tijdsduur en l_bdl_eenheid hebben een waarde.
SELECT mld.geteinddatum(p_melding_key,
MLD_T_UITVOERTIJD(l_bdl_tijdsduur, l_bdl_eenheid),
SYSDATE)
INTO l_mld_opdr_einddatum
FROM DUAL;
-- Als setting mld_enforce_orderdates = 1, dan moeten de datums van de opdracht binnen de datums van de melding liggen.
IF l_mld_typeopdr_slamode = 1 AND
fac.getsetting('mld_enforce_orderdates') = 1 AND
TRUNC(l_mld_melding_einddatum, 'DDD') < TRUNC(l_mld_opdr_einddatum, 'DDD')
THEN
l_mld_opdr_einddatum := l_mld_melding_einddatum;
END IF;
END IF;
ELSE
l_mld_opdr_einddatum := l_mld_melding_einddatum; -- Einddatum melding;
END IF;
-- Opdracht omschrijving.
IF l_mld_melding_onderwerp IS NOT NULL
THEN
l_mld_opdr_omschrijving := l_mld_melding_onderwerp;
IF l_mld_melding_omschrijving IS NOT NULL
THEN
l_mld_opdr_omschrijving := l_mld_opdr_omschrijving || CHR(10);
END IF;
END IF;
IF l_mld_melding_omschrijving IS NOT NULL
THEN
l_mld_opdr_omschrijving := l_mld_opdr_omschrijving || l_mld_melding_omschrijving;
END IF;
IF fac.getsetting('mld_ord_flexsummary') = 1
THEN
l_mld_opdr_omschrijving := l_mld_opdr_omschrijving || mld.mldflexsummary(p_melding_key);
END IF;
SELECT mld_s_mld_opdr_key.NEXTVAL INTO l_new_opdr_key FROM DUAL;
-- Merk op: voor sommige velden laten we bewust de default nemen
INSERT INTO mld_opdr (mld_melding_key,
mld_opdr_key,
mld_opdr_bedrijfopdr_volgnr,
mld_typeopdr_key,
mld_uitvoerende_keys,
prs_perslid_key,
prs_kostenplaats_key,
prs_kostensoort_key,
mld_opdr_kosten,
mld_opdr_uurloon,
mld_opdr_uren,
mld_opdr_module,
mld_opdr_datumbegin,
mld_opdr_einddatum,
mld_opdr_omschrijving)
VALUES (p_melding_key,
l_new_opdr_key,
mld.bepaalopdrmeldingvolgnr(p_melding_key),
l_mld_typeopdr_key,
l_prs_bedrijf_key,
CASE
WHEN l_haswrite = 1
THEN l_prs_perslid_key
ELSE NULL
END,
l_prs_kostenplaats_key,
l_prs_kostensoort_key,
l_mld_stdmelding_autoorderamnt,
l_prs_bedrijf_uurloon,
0,
'MLD',
SYSDATE, -- Begindatum opdracht gelijk aan de melding datum (SYSDATE voor workflow melding).
l_mld_opdr_einddatum,
l_mld_opdr_omschrijving);
-- Status en tracking altijd met de functie setopdrachtstatus
-- Zetten van de status van een nieuwe opdracht op nieuw en afhandelen van de tracking (status + uitvoerende tracking) en daarmee notificatie.
IF l_mld_stdmelding_autoorderamnt > l_mld_disc_params_bestellimiet OR l_mld_stdmelding_autoorderamnt > l_mld_typeopdr_gvs
THEN
mld.setopdrachtstatus(l_new_opdr_key, 10, NULL); -- Ter goedkeuring.
ELSIF l_for_approval AND l_prs_kostenplaats_fiat = 1 AND l_mld_stdmelding_autoorderamnt > l_mld_typeopdr_fvs -- We moeten fiatteren en er is geen (of een te lage) fiatteringsvrijstelling
THEN
mld.setopdrachtstatus(l_new_opdr_key, 3, NULL); -- Ter fiattering.
ELSE
-- Fiatteren niet nodig.
mld.setopdrachtstatus(l_new_opdr_key, 5, NULL); -- Uitgegeven.
-- mld.trackuitvoerende(opdr_key, uitvoerende, opdr_status_key);
SELECT CASE
WHEN u.intern = 1
THEN 'ORDMLI'
ELSE 'ORDMLE'
END
INTO l_action
FROM mld_v_uitvoerende u
WHERE u.mld_uitvoerende_key = l_prs_bedrijf_key;
-- Type "P" (persoon) is intern en type "B" (bedrijf) is afhankelijk van "prs_bedrijf_intern" intern of extern.
fac.trackaction(l_action, l_new_opdr_key, NULL, NULL, NULL);
-- In de database procedure doen we geen putorders.sendnotifications(pkey, paction). Dan moeten we maar iets langer wachten.
END IF;
-- Refresh meldingstatus zonodig als gevolg van een nieuw uitgegeven opdracht.
-- Als er open opdrachten zijn wordt de melding op Uitgegeven gezet als dat al niet zo was.
mld.updatemeldingstatus (p_melding_key, 0, NULL);
-- (Re)calculate the conditionscores of the releated objects
IF fac.getsetting('cnd_gebreken_srtdisc_key') > 0
THEN
cnd.process_mjb_score_effects(p_melding_key, NULL);
END IF;
-- Bij workflow meldingen worden de bijlagen niet gekopieerd.
-- De bijlagen van de parent melding worden bij de onderliggende workflow melding weergegeven (in de show mode)
-- als de instelling/setting "mld_show_parent_attachments" is gezet.
-- Bij het automatisch aanmaken van de opdracht bij een workflowmelding hoeven dus ook geen bijlagen te worden gekopieerd.
-- Bij het automatisch aanmaken van een opdracht bij een melding is alleen de melding_key doorgegeven en dus niet de melding kenmerken.
-- Deze kenmerken zijn dus ook niet opgeslagen.
-- De melding kenmerken die overeenkomen met de opdracht kenmerken (dezelfde omschrijving en srtkenmerk) ophalen en opslaan voor de nieuwe opdracht.
INSERT INTO mld_kenmerkopdr (mld_opdr_key
, mld_kenmerk_key
, mld_kenmerkopdr_waarde)
SELECT l_new_opdr_key mld_opdr_key
, k.mld_kenmerk_key kenmerk_key
, COALESCE((SELECT v.mld_kenmerkmelding_waarde
FROM mld_kenmerkmelding v
, mld_kenmerk vk
, mld_srtkenmerk vt
WHERE v.mld_melding_key = p_melding_key
AND vk.mld_srtkenmerk_key = vt.mld_srtkenmerk_key
AND vk.mld_srtkenmerk_key = k.mld_srtkenmerk_key
AND vk.mld_kenmerk_groep = k.mld_kenmerk_groep
AND v.mld_kenmerk_key = vk.mld_kenmerk_key
AND v.mld_kenmerkmelding_verwijder IS NULL
AND COALESCE(vk.mld_kenmerk_omschrijving, vt.mld_srtkenmerk_omschrijving) = COALESCE(k.mld_kenmerk_omschrijving, t.mld_srtkenmerk_omschrijving)),
k.mld_kenmerk_default) kenmerk_waarde
FROM mld_srtkenmerk t
, mld_kenmerk k
, mld_typeopdr s
WHERE (s.mld_typeopdr_key = l_mld_typeopdr_key OR s.mld_typeopdr_key IS NULL)
AND k.mld_typeopdr_key = s.mld_typeopdr_key(+)
AND k.mld_kenmerk_niveau IN ('P', 'O')
AND k.mld_kenmerk_verwijder IS NULL
AND k.mld_srtkenmerk_key = t.mld_srtkenmerk_key
AND t.mld_srtkenmerk_verwijder IS NULL
AND t.mld_srtkenmerk_kenmerktype <> 'M'
AND (k.mld_kenmerk_volgnummer <= 100
OR k.mld_kenmerk_volgnummer >= 900) -- Alleen bij of na afmelden mogen afmeld-kenmerken tussen de 100..900
AND COALESCE((SELECT v.mld_kenmerkmelding_waarde
FROM mld_kenmerkmelding v
, mld_kenmerk vk
, mld_srtkenmerk vt
WHERE v.mld_melding_key = p_melding_key
AND vk.mld_srtkenmerk_key = vt.mld_srtkenmerk_key
AND vk.mld_srtkenmerk_key = k.mld_srtkenmerk_key
AND vk.mld_kenmerk_groep = k.mld_kenmerk_groep
AND v.mld_kenmerk_key = vk.mld_kenmerk_key
AND v.mld_kenmerkmelding_verwijder IS NULL
AND COALESCE(vk.mld_kenmerk_omschrijving, vt.mld_srtkenmerk_omschrijving) = COALESCE(k.mld_kenmerk_omschrijving, t.mld_srtkenmerk_omschrijving)),
k.mld_kenmerk_default) IS NOT NULL
AND COALESCE((SELECT v.mld_kenmerkmelding_waarde
FROM mld_kenmerkmelding v
, mld_kenmerk vk
, mld_srtkenmerk vt
WHERE v.mld_melding_key = p_melding_key
AND vk.mld_srtkenmerk_key = vt.mld_srtkenmerk_key
AND vk.mld_srtkenmerk_key = k.mld_srtkenmerk_key
AND vk.mld_kenmerk_groep = k.mld_kenmerk_groep
AND v.mld_kenmerk_key = vk.mld_kenmerk_key
AND v.mld_kenmerkmelding_verwijder IS NULL
AND COALESCE(vk.mld_kenmerk_omschrijving, vt.mld_srtkenmerk_omschrijving) = COALESCE(k.mld_kenmerk_omschrijving, t.mld_srtkenmerk_omschrijving)),
k.mld_kenmerk_default) NOT LIKE '%##EXPR##%';
INSERT INTO fac_kenmwaarden(fac_kenmwaarden_module,
fac_kenmwaarden_refkey,
fac_kenmwaarden_kenmerk_key,
fac_kenmwaarden_waarde,
fac_kenmwaarden_kenmerktype,
fac_kenmwaarden_kenmerklen,
fac_kenmwaarden_kenmerkdec,
fac_kenmwaarden_isexpr,
prs_perslid_key)
SELECT 'OPD',
l_new_opdr_key,
k.mld_kenmerk_key,
COALESCE((SELECT v.mld_kenmerkmelding_waarde
FROM mld_kenmerkmelding v,
mld_kenmerk vk,
mld_srtkenmerk vt
WHERE v.mld_melding_key = p_melding_key
AND vk.mld_srtkenmerk_key = vt.mld_srtkenmerk_key
AND vk.mld_srtkenmerk_key = k.mld_srtkenmerk_key
AND vk.mld_kenmerk_groep = k.mld_kenmerk_groep
AND v.mld_kenmerk_key = vk.mld_kenmerk_key
AND v.mld_kenmerkmelding_verwijder IS NULL
AND COALESCE(vk.mld_kenmerk_omschrijving, vt.mld_srtkenmerk_omschrijving) = COALESCE(k.mld_kenmerk_omschrijving, t.mld_srtkenmerk_omschrijving)),
k.mld_kenmerk_default) kenmerk_waarde,
t.mld_srtkenmerk_kenmerktype,
t.mld_srtkenmerk_lengte,
t.mld_srtkenmerk_dec,
CASE
WHEN k.mld_kenmerk_default LIKE '%##EXPR##%'
THEN 1
ELSE 0
END fac_kenmwaarden_isexpr,
l_prs_perslid_key
FROM mld_srtkenmerk t
, mld_kenmerk k
, mld_typeopdr s
WHERE (s.mld_typeopdr_key = l_mld_typeopdr_key OR s.mld_typeopdr_key IS NULL)
AND k.mld_typeopdr_key = s.mld_typeopdr_key(+)
AND k.mld_kenmerk_niveau IN ('P', 'O')
AND k.mld_kenmerk_verwijder IS NULL
AND k.mld_srtkenmerk_key = t.mld_srtkenmerk_key
AND t.mld_srtkenmerk_verwijder IS NULL
AND t.mld_srtkenmerk_kenmerktype <> 'M'
AND (k.mld_kenmerk_volgnummer <= 100
OR k.mld_kenmerk_volgnummer >= 900) -- Alleen bij of na afmelden mogen afmeld-kenmerken tussen de 100..900
AND COALESCE((SELECT MIN(v.mld_kenmerkmelding_waarde)
FROM mld_kenmerkmelding v
, mld_kenmerk vk
, mld_srtkenmerk vt
WHERE v.mld_melding_key = p_melding_key
AND vk.mld_srtkenmerk_key = vt.mld_srtkenmerk_key
AND vk.mld_srtkenmerk_key = k.mld_srtkenmerk_key
AND vk.mld_kenmerk_groep = k.mld_kenmerk_groep
AND v.mld_kenmerk_key = vk.mld_kenmerk_key
AND v.mld_kenmerkmelding_verwijder IS NULL),
k.mld_kenmerk_default) IS NOT NULL
ORDER BY mld_kenmerk_volgnummer;
-- Evaluate flex expressions.
flx.evaluateflexexpressions('OPD', l_new_opdr_key, l_prs_perslid_key, 1);
-- De nieuwe (offerte)opdracht door putorders laten oppikken (te verzenden veld zetten), zodat de opdracht verstuurd wordt.
IF l_mld_typeopdr_isofferte = 1
THEN
-- Offerte.
UPDATE mld_opdr
SET mld_opdr_teverzenden = 1
WHERE mld_opdr_key = l_new_opdr_key;
ELSE
-- Alleen in geval van een uitvoerder, de opdracht door putorders laten oppikken.
BEGIN
SELECT prs_bedrijfadres_url
INTO l_prs_bedrijfadres_url
FROM prs_bedrijfadres
WHERE prs_bedrijfadres_type = 'O'
AND (mld_typeopdr_key IS NULL
OR mld_typeopdr_key = l_mld_typeopdr_key)
AND (alg_locatie_key = l_mld_alg_locatie_key
OR alg_locatie_key IS NULL)
AND (alg_district_key = (SELECT d.alg_district_key
FROM alg_locatie d
WHERE d.alg_locatie_key = l_mld_alg_locatie_key)
OR alg_district_key IS NULL)
AND prs_bedrijf_key = l_prs_bedrijf_key;
UPDATE mld_opdr
SET mld_opdr_teverzenden = 1
WHERE mld_opdr_key = l_new_opdr_key;
EXCEPTION
WHEN NO_DATA_FOUND
THEN NULL;
END;
END IF;
END mld_addautoorder;
PROCEDURE mld_nextworkflowstep (p_melding_key IN NUMBER, p_success IN NUMBER)
AS
-- p_melding_key key of the call to be continued
-- p_success gives state of the executed call:
-- 0 = rejected (reinstated since DB8)
-- 1 = completed
-- -1 = initial (the originating call)
l_melding_start_key NUMBER (10);
l_workflowstep_key NUMBER (10);
l_stdmelding_key NUMBER (10);
l_workflowstep_next_key NUMBER (10);
l_new_melding_key NUMBER (10);
l_success NUMBER;
l_nrofreadypredecessors NUMBER;
l_nrofactualpredecessors NUMBER;
l_nrofpossiblepredecessors NUMBER;
l_nrofrequiredpredecessors NUMBER;
l_prepredecessors NUMBER;
tmp NUMBER;
createthisnextstep BOOLEAN;
rootregistered BOOLEAN;
l_nrstepsevaluatedtrue NUMBER := 0;
nrcase_a NUMBER := 0;
nrcase_b NUMBER := 0;
l_common_ancestor mld_workflowrule.mld_workflowstep_key%TYPE;
l_initmldstatus mld_melding.mld_melding_status%TYPE;
calculated_einddatum mld_melding.mld_melding_einddatum%TYPE;
root_einddatum mld_melding.mld_melding_einddatum%TYPE;
l_autoorder mld_stdmelding.mld_stdmelding_autoorder%TYPE;
BEGIN
l_success := p_success;
BEGIN
SELECT mld_melding_start_key, mld_workflowstep_key, mld_stdmelding_key
INTO l_melding_start_key, l_workflowstep_key, l_stdmelding_key
FROM mld_melding
WHERE mld_melding_key = p_melding_key;
EXCEPTION
WHEN NO_DATA_FOUND
THEN
-- Internal error; mld_melding must exist
RETURN;
END;
IF p_success = -1
THEN
-- The first step of a workflow
BEGIN
SELECT ws.mld_workflowstep_key
INTO l_workflowstep_key
FROM mld_workflowstep ws
WHERE ws.mld_stdmelding_key = l_stdmelding_key
AND ws.mld_workflowstep_start_key IS NULL;
EXCEPTION
WHEN NO_DATA_FOUND
THEN
-- No workflowsteps defined for this type of calls
RETURN;
WHEN TOO_MANY_ROWS
THEN
-- Workflow defined more than once, is erroneous; do not know what to do so
RETURN;
END;
-- We must implicitly accept the initial call once, else we cannot complete it later
-- and accepting in the end would be odd.
mld.setmeldingstatus (p_melding_key, 4, NULL);
rootregistered := FALSE;
l_melding_start_key := p_melding_key;
l_success := 1; -- we used the info, we continue like success
END IF;
-- Is this mld_melding part of a workflow?
IF l_workflowstep_key IS NULL
THEN
-- No, done.
RETURN;
END IF;
-- Als dit niet NULL waarden oplevert, dan is deze melding onderdeel van een workflow process
-- Bepaal nu de vervolgstappen binnen deze workflow (zelfde start_key).
-- Dit kunnen er meerdere zijn.
DECLARE
-- This cursor yields all the next workflowssteps as defined in this workflow
-- That does not necessarily mean that all these steps will be created at this time!
-- That actual creating depends on whether the condition evaluates to true and
-- the state of dependent steps if any and as defined by jointype
--
-- TODO: think about the exact behaviour of mld_workflowrule_result
CURSOR c_nextsteps
IS
SELECT ws.mld_workflowstep_key,
ws.mld_stdmelding_key,
stdm.mld_ins_discipline_key,
stdm.mld_stdmelding_default_disc,
disc.ins_srtdiscipline_key,
wr.mld_workflowrule_condition,
ws.mld_workflowstep_jointype,
ws.mld_workflowstep_eindtype,
COALESCE(stdm.mld_stdmelding_directklaar, dp.mld_disc_params_directklaar, 0) mld_directklaar
FROM mld_workflowrule wr, -- alles wat begint op de huidige step
mld_workflowstep ws0, -- de huidige step, voor de start_key
mld_workflowstep ws, -- alle volgende stappen
mld_stdmelding stdm, -- de melding van een volgende step
mld_discipline disc,
mld_disc_params dp
WHERE stdm.mld_stdmelding_key = ws.mld_stdmelding_key
AND stdm.mld_ins_discipline_key = disc.ins_discipline_key
AND stdm.mld_ins_discipline_key = dp.mld_ins_discipline_key
AND wr.mld_workflowstep_key = ws0.mld_workflowstep_key
AND ws.mld_workflowstep_start_key =
NVL (ws0.mld_workflowstep_start_key, ws.mld_workflowstep_start_key)
AND wr.mld_workflowstep_next_key = ws.mld_workflowstep_key
AND wr.mld_workflowrule_result = l_success
AND wr.mld_workflowstep_key = l_workflowstep_key;
r_nextsteps c_nextsteps%ROWTYPE;
FUNCTION evaluatecondition (p_mld_key IN NUMBER, p_where IN VARCHAR2)
RETURN BOOLEAN
AS
l_sql VARCHAR2 (4000);
l_rowsprocessed NUMBER DEFAULT 0;
l_cursor INTEGER DEFAULT DBMS_SQL.open_cursor;
l_cntbind NUMBER;
l_cnt NUMBER;
l_bvar VARCHAR2 (1000);
l_rflex VARCHAR2 (1000) DEFAULT '(\:flex[0-9_]+)'; -- supports ':flex111 = ''538'''
l_kenmerkwaarde mld_kenmerkmelding.mld_kenmerkmelding_waarde%TYPE;
l_kenmerk_key mld_kenmerkmelding.mld_kenmerk_key%TYPE;
BEGIN
IF p_where IS NULL
THEN
RETURN TRUE;
END IF;
l_sql := 'select 1 from mld_melding where mld_melding_key = :mld_key AND ' || p_where;
DBMS_OUTPUT.put_line (l_sql);
DBMS_SQL.parse (l_cursor, l_sql, DBMS_SQL.native);
DBMS_SQL.bind_variable (l_cursor, ':mld_key', p_mld_key);
l_cntbind :=
REGEXP_COUNT (l_sql,
l_rflex,
1,
'i');
DBMS_OUTPUT.put_line ('nBindvars: ' || TO_CHAR (l_cntbind));
FOR l_cnt IN 1 .. l_cntbind LOOP
l_bvar :=
REGEXP_SUBSTR (l_sql,
l_rflex,
1,
l_cnt,
'i');
DBMS_OUTPUT.put_line ('Bindvar: ' || l_bvar);
l_kenmerk_key := TO_NUMBER (SUBSTR (l_bvar, 6));
DBMS_OUTPUT.put_line ('Bindvarkey: ' || l_kenmerk_key);
BEGIN
SELECT mld_kenmerkmelding_waarde
INTO l_kenmerkwaarde
FROM mld_kenmerkmelding
WHERE mld_melding_key = p_mld_key AND mld_kenmerk_key = l_kenmerk_key;
EXCEPTION
WHEN NO_DATA_FOUND
THEN
l_kenmerkwaarde := NULL;
END;
DBMS_SQL.bind_variable (l_cursor, l_bvar, l_kenmerkwaarde);
END LOOP;
l_rowsprocessed := DBMS_SQL.execute_and_fetch (l_cursor);
DBMS_SQL.close_cursor(l_cursor);
RETURN l_rowsprocessed = 1;
END;
BEGIN
OPEN c_nextsteps;
FETCH c_nextsteps INTO r_nextsteps;
IF c_nextsteps%NOTFOUND
THEN
-- If no l_workflowstep_next_key was found, this workflow is done
-- THEN, close the originating l_melding_start_key
-- But only if there are no other threads open!
SELECT COUNT (mld_melding_key)
INTO tmp
FROM mld_melding
WHERE mld_melding_start_key = l_melding_start_key
AND mld_workflowstep_key IS NOT NULL -- tel toevallige adhoc vervolgmeldingen niet mee
AND mld_melding_status NOT IN (1, 5, 6)
AND mld_melding_key <> l_melding_start_key;
-- Als er geen lopende parallelle meldingen zijn, OF DEZE (eenzame) STAP WORDT AFGEWEZEN
-- Dan sluit de root. Overwogen dat de root niet Afgewezen wordt bij 0.
IF tmp = 0 OR l_success = 0
THEN
DBMS_OUTPUT.put_line ('Closing parent:' || l_melding_start_key);
mld.setmeldingstatus (l_melding_start_key, 5, NULL);
--ELSE
--DBMS_OUTPUT.PUT_LINE('no more steps, but still ' || tmp || ' open calls in workflow');
END IF;
--More?
RETURN;
ELSE
-- For each found l_workflowstep_next_key, create a new mld_melding
-- if condition evaluates to true
-- Using the basic properties of l_melding_start_key
-- and the flexprops of p_melding_key if these match the mld_srtkenmerk_key
LOOP
DBMS_OUTPUT.put_line( 'startkey:'
|| l_melding_start_key
|| ' step key:'
|| r_nextsteps.mld_workflowstep_key);
SELECT COUNT ( * )
INTO l_nrofpossiblepredecessors
FROM mld_workflowrule wr1, mld_workflowstep ws1
WHERE wr1.mld_workflowstep_key = ws1.mld_workflowstep_key
AND wr1.mld_workflowstep_next_key = r_nextsteps.mld_workflowstep_key;
DBMS_OUTPUT.put_line (
'total nr of possible predecessors for next step: ' || l_nrofpossiblepredecessors);
SELECT COUNT ( * )
INTO l_nrofactualpredecessors -- disregard status
FROM mld_melding m
WHERE m.mld_workflowstep_key IN
(SELECT wr1.mld_workflowstep_key
FROM mld_workflowrule wr1, mld_workflowstep ws1
WHERE wr1.mld_workflowstep_key = ws1.mld_workflowstep_key
AND wr1.mld_workflowstep_next_key =
r_nextsteps.mld_workflowstep_key)
-- the step to be continued
AND mld_melding_start_key = l_melding_start_key; -- for this thread
DBMS_OUTPUT.put_line('total nr of actual predecessors for next step: '
|| l_nrofactualpredecessors);
l_nrofrequiredpredecessors := l_nrofactualpredecessors;
-- If there is a difference between l_nrofpossiblepredecessors and l_nrofactualpredecessors there are
-- a few possibilities:
-- a. an actual predecessor has not been started yet (workflow branches are unequal length)
-- b. an actual predecessor has not been started and will not start due to a condition
-- In case a. the predecessor will start eventually and then trigger the next step.
-- Then l_nrofreadypredecessors = l_nrofpossiblepredecessors
-- In case b. the l_nrofreadypredecessors will never reach l_nrofpossiblepredecessors, the
-- next step will be triggered when l_nrofreadypredecessors = l_nrofactualpredecessors
-- The question is: how do we distinguish a and b?
--
-- Suggestion: backtracking the workflow for the step that is not (yet) there?
IF l_nrofpossiblepredecessors > l_nrofactualpredecessors
THEN
BEGIN
SELECT wr1.mld_workflowstep_key
INTO l_common_ancestor
FROM mld_workflowrule wr1, mld_workflowstep ws1
WHERE wr1.mld_workflowstep_key = ws1.mld_workflowstep_key
AND wr1.mld_workflowstep_next_key IN
(SELECT wr1.mld_workflowstep_key
FROM mld_workflowrule wr1, mld_workflowstep ws1
WHERE wr1.mld_workflowstep_key = ws1.mld_workflowstep_key
AND wr1.mld_workflowstep_next_key = r_nextsteps.mld_workflowstep_key)
GROUP BY wr1.mld_workflowstep_key;
EXCEPTION
WHEN NO_DATA_FOUND OR TOO_MANY_ROWS
THEN
l_common_ancestor := -1;
END;
IF l_common_ancestor <> -1
THEN
DBMS_OUTPUT.put_line ('Common ancestor detected for all previous workflowsteps, so a condition not met (case b)');
l_nrofrequiredpredecessors := l_nrofactualpredecessors;
ELSE
-- determine case a or case b
FOR missingsteps
IN (SELECT wr1.mld_workflowstep_key
FROM mld_workflowrule wr1, mld_workflowstep ws1
WHERE wr1.mld_workflowstep_key = ws1.mld_workflowstep_key
AND wr1.mld_workflowstep_next_key =
r_nextsteps.mld_workflowstep_key
MINUS
SELECT mld_workflowstep_key
FROM mld_melding m
WHERE m.mld_workflowstep_key IN
(SELECT wr1.mld_workflowstep_key
FROM mld_workflowrule wr1, mld_workflowstep ws1
WHERE wr1.mld_workflowstep_key = ws1.mld_workflowstep_key
AND wr1.mld_workflowstep_next_key =
r_nextsteps.mld_workflowstep_key)
AND mld_melding_start_key = l_melding_start_key) LOOP
-- This predecessing step missingsteps.mld_workflowstep_key is possible but not actual. How come?
-- Are some of its predecessor(s) not being the root actual in this workflow?
-- NOTE THAT THIS NEEDS ATTENTION IF WE NEED TO SUPPORT LONGER, UNBALANCED, CONDITIONAL WORKFLOWS
-- WE DO NOT SUPPORT THOSE HERE AND NOW, AND PROBABLY NO ONE WILL EVER NOTICE
SELECT COUNT ( * )
INTO l_prepredecessors
FROM mld_melding m
WHERE m.mld_workflowstep_key IN
(SELECT wr1.mld_workflowstep_key
FROM mld_workflowrule wr1, mld_workflowstep ws1
WHERE wr1.mld_workflowstep_key = ws1.mld_workflowstep_key
AND wr1.mld_workflowstep_next_key =
missingsteps.mld_workflowstep_key)
AND mld_melding_key <> l_melding_start_key
AND mld_melding_start_key = l_melding_start_key;
DBMS_OUTPUT.put_line('Complex case! Total nr of actual prepredecessors for predecessor-step '
|| missingsteps.mld_workflowstep_key
|| ': '
|| l_prepredecessors);
IF l_prepredecessors = 0
THEN
-- Prepredecessor is presumably the root, so it must be a false condition that prevented
-- the step from being actual. It will never become existing, so case b
nrcase_b := nrcase_b + 1; -- we probably do not need this nr
ELSE
-- there are actual prepredecessors, case a
nrcase_a := nrcase_a + 1;
END IF;
END LOOP;
-- Now we checked all predecessors, which one do we choose?
-- If one case a exists, we should act like ...?
IF nrcase_a > 0
THEN
l_nrofrequiredpredecessors := l_nrofactualpredecessors + nrcase_a; --l_nrofpossiblepredecessors;
END IF;
END IF;
ELSE
-- both are the same, just pick one to test against later
l_nrofrequiredpredecessors := l_nrofactualpredecessors;
END IF;
DBMS_OUTPUT.put_line('total nr of required predecessors for next step: '
|| l_nrofrequiredpredecessors);
SELECT COUNT ( * )
INTO l_nrofreadypredecessors
FROM mld_melding m
WHERE m.mld_workflowstep_key IN
(SELECT wr1.mld_workflowstep_key
FROM mld_workflowrule wr1, mld_workflowstep ws1
WHERE wr1.mld_workflowstep_key = ws1.mld_workflowstep_key
AND wr1.mld_workflowstep_next_key =
r_nextsteps.mld_workflowstep_key)
-- the step to be continued
AND mld_melding_status IN (1, 5, 6) -- predecessor has been handled, no matter how
AND mld_melding_start_key = l_melding_start_key; -- for this thread
DBMS_OUTPUT.put_line (
'total nr of READY predecessors for next step: ' || l_nrofreadypredecessors);
createthisnextstep := FALSE;
-- What we do next depends on the jointype. We are one predecessor ourselves. Options are:
---- Exact one predecessor which is obviously ready (else we would not be called): start all next steps where that rule condition evaluates to true
---- Multiple predecessors:
------ jointype 0 (AND): all predecessors must be ready, if not do not start any next steps
------ jointype 1 (OR): at least one predecessor must be ready. Since we are called, this must be the case,
------ unless that step has already been started by a previous call, then we should start
------ these next steps again [next level: update flexprops of already started calls?]
------ jointype 2 (SYNC): all actually started predecessors must be ready. These predecessors are defined
------ by the workflow but the actual runtime condition may have prevented that step to be created
------ in which case that step should be neglected
---- if jointype is null is is treated as 0 (AND)
------ Note: i am not really sure if l_nrofpossiblepredecessors is always the right one to check against
-- TE OVERWEGEN: NULL IS GEEN JOIN, DUS SEQUENCE OF SPLIT, DUS HOEF IK NIKS TE TELLEN, APARTE CASE ZONDER BOVENSTAANDE QUERIES?
-- When p_success = -1 there is no predecessor, no jointype, so NULL/0
CASE r_nextsteps.mld_workflowstep_jointype
WHEN 0
THEN -- AND
createthisnextstep :=
l_nrofreadypredecessors >= l_nrofrequiredpredecessors OR p_success = -1;
WHEN 1
THEN -- OR
createthisnextstep := l_nrofreadypredecessors = 1;
-- if l_nrofreadypredecessors > 1 the creation has already taken place :-)
WHEN 2
THEN -- SYNC
-- Wel nog een beetje raar in onze <20>naar mijn groeiende overtuiging slimmere- implementatie:
-- dit wil je altijd als je condities toepast, ook met een AND. Je wilt toch nooit wachten op een voorganger die niet bestaat?!?
-- Onze traditionele AND lijkt me een SYNC, en dan is deze mode toch niet nodig.
createthisnextstep := l_nrofreadypredecessors >= l_nrofrequiredpredecessors;
END CASE;
IF createthisnextstep
THEN
DBMS_OUTPUT.put_line (
'We GO for the next step ' || r_nextsteps.mld_workflowstep_key);
IF evaluatecondition (p_melding_key, r_nextsteps.mld_workflowrule_condition)
THEN
-- We mark the initial call as the workflow-root. We may only do this if at least one
-- nextstep-condition evaluates to true or we might end up with a root without steps
IF p_success = -1 AND NOT rootregistered
THEN
UPDATE mld_melding
SET mld_workflowstep_key = l_workflowstep_key,
mld_melding_start_key = p_melding_key -- do we need this or not? choose!
WHERE mld_melding_key = p_melding_key;
rootregistered := TRUE;
END IF;
DBMS_OUTPUT.put_line (
'We actually start the next step ' || r_nextsteps.mld_workflowstep_key);
l_nrstepsevaluatedtrue := l_nrstepsevaluatedtrue + 1;
IF r_nextsteps.mld_directklaar = 2
THEN
l_initmldstatus := 0;
ELSE
l_initmldstatus := 2;
END IF;
SELECT mld_s_mld_melding_key.NEXTVAL INTO l_new_melding_key FROM DUAL;
-- Merk op: voor sommige velden laten we bewust de default nemen
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_onderwerp,
mld_melding_omschrijving,
mld_melding_opmerking,
mld_stdmelding_key,
mld_melding_status,
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,
mld_ins_discipline_key)
SELECT l_new_melding_key,
mld_melding_module,
mld_meldbron_key,
mld_alg_locatie_key,
mld_alg_onroerendgoed_keys,
SYSDATE,
mld_melding_onderwerp,
mld_melding_omschrijving,
lcl.l ('lcl_mld_wf_generated_by')
|| p_melding_key
|| '. '
|| mld_melding_opmerking,
r_nextsteps.mld_stdmelding_key,
l_initmldstatus,
mld_kosten_klant,
mld_melding_document,
m.prs_kostenplaats_key,
prs_perslid_key,
mld_adres_key,
r_nextsteps.mld_workflowstep_key,
l_melding_start_key,
mld_melding_ordernr,
mld_melding_spoed,
r_nextsteps.mld_stdmelding_default_disc
FROM mld_melding m,
mld_stdmelding msm
WHERE mld_melding_key = l_melding_start_key
AND msm.mld_stdmelding_key = r_nextsteps.mld_stdmelding_key;
IF r_nextsteps.mld_workflowstep_eindtype = 1
THEN
-- 1 = limit to the enddate of the root, if needed.
-- calculating the end date can be complex, we let the triggers do their job and
-- check afterwards whether we need to alter it
SELECT mld_melding_einddatum
INTO calculated_einddatum
FROM mld_melding
WHERE mld_melding_key = l_new_melding_key;
SELECT mld_melding_einddatum
INTO root_einddatum
FROM mld_melding
WHERE mld_melding_key = l_melding_start_key;
IF calculated_einddatum > root_einddatum
THEN
UPDATE mld_melding
SET mld_melding_einddatum = root_einddatum
WHERE mld_melding_key = l_new_melding_key;
END IF;
END IF;
fac.trackaction ('MLDNEW',
l_new_melding_key,
NULL,
NULL,
NULL); -- ook mld2bo notificatie
IF r_nextsteps.mld_stdmelding_default_disc IS NOT NULL -- mldbhg notificatie
THEN
mld.notifybackoffice (l_new_melding_key, 'MLDBHG', 2);
END IF;
-- Kopieer nu de objecten mee als je dat wilt
IF fac.getsetting('mld_copy_objects_in_workflow') = 1
THEN
INSERT INTO mld_melding_object (mld_melding_key, ins_deel_key)
SELECT l_new_melding_key, ins_deel_key
FROM mld_melding_object
WHERE mld_melding_key = p_melding_key
AND mld_melding_object_verwijder is null;
END IF;
-- Kopieer nu de flexkenmerken voor zover deze bij oud-EN-nieuw bestaan
DECLARE
CURSOR c_mld_kenmerken
IS
-- VERRASSEND, SLIPGEVAAR, lastige materie
-- Dit zijn (nu) alle ingevulde kenmerken van de voorlopende meldingen,
-- per soortkenmerk gesorteerd zdd de LAATST AANGEMAAKTE MELDING (hogere key)
-- eerst komt.
-- Verderop wordt steeds alleen de eerste beschouwd.
-- Dat betekent de de kenmerken van de melding die later in een workflow
-- worden aangepast sterker zijn dan de eerdere.
-- Een echt hele goeie oplossing is niet mogelijk.
-- Pas ook op: bij de voorgaande meldingen kunnen ook zomaar de vervolgstappen
-- betrokken worden die hierboven net aangemaakt zijn. Dat vinden we niet erg
-- want die zijn dan immers zojuist ook op dezelfde manier bepaald.
-- Eerst de MAX van de meldingen bepalen en van die melding halen we de mld_kenmerkmelding_waarde op.
SELECT km.mld_kenmerkmelding_waarde,
k.mld_srtkenmerk_key,
mkm.mld_melding_key,
k.mld_kenmerk_groep,
COALESCE(k.mld_kenmerk_omschrijving, s.mld_srtkenmerk_omschrijving) mld_kenmerk_omschrijving
FROM mld_kenmerkmelding km,
mld_kenmerk k,
mld_melding m,
mld_srtkenmerk s,
(SELECT k1.mld_srtkenmerk_key,
MAX(m1.mld_melding_key) mld_melding_key,
k1.mld_kenmerk_groep,
COALESCE(k1.mld_kenmerk_omschrijving, s1.mld_srtkenmerk_omschrijving) mld_kenmerk_omschrijving
FROM mld_kenmerkmelding km1,
mld_kenmerk k1,
mld_melding m1,
mld_srtkenmerk s1
WHERE km1.mld_kenmerkmelding_verwijder IS NULL
AND km1.mld_kenmerk_key = k1.mld_kenmerk_key
AND km1.mld_melding_key = m1.mld_melding_key
AND k1.mld_srtkenmerk_key = s1.mld_srtkenmerk_key
AND s1.mld_srtkenmerk_kenmerktype NOT IN ('F', 'E')
AND m1.mld_melding_start_key = l_melding_start_key
AND m1.mld_melding_key < l_new_melding_key
AND mld_workflowstep_key IS NOT NULL
GROUP BY k1.mld_srtkenmerk_key,
k1.mld_kenmerk_groep,
k1.mld_kenmerk_omschrijving,
s1.mld_srtkenmerk_omschrijving) mkm
WHERE km.mld_kenmerkmelding_verwijder IS NULL
AND km.mld_kenmerk_key = k.mld_kenmerk_key
AND km.mld_melding_key = m.mld_melding_key
AND k.mld_kenmerk_groep = mkm.mld_kenmerk_groep
AND km.mld_melding_key = mkm.mld_melding_key
AND k.mld_srtkenmerk_key = s.mld_srtkenmerk_key
AND s.mld_srtkenmerk_key = mkm.mld_srtkenmerk_key
AND s.mld_srtkenmerk_kenmerktype NOT IN ('F', 'E')
AND m.mld_melding_start_key = l_melding_start_key
AND m.mld_melding_key < l_new_melding_key
AND mld_workflowstep_key IS NOT NULL
AND COALESCE(k.mld_kenmerk_omschrijving, s.mld_srtkenmerk_omschrijving) = mkm.mld_kenmerk_omschrijving
ORDER BY 2,
4,
3 DESC,
5;
r_mld_kenmerken c_mld_kenmerken%ROWTYPE;
l_new_kenmerk_key NUMBER (10);
wasbezigmetsrtkenmerk NUMBER (10);
wasbezigmetgroep NUMBER (10);
wasbezigmetomschrijving VARCHAR2 (50);
benbezigmetsrtkenmerk NUMBER (10);
benbezigmetgroep NUMBER (10);
benbezigmetomschrijving VARCHAR2 (50);
BEGIN
wasbezigmetsrtkenmerk := -1;
wasbezigmetgroep := -1;
wasbezigmetomschrijving := NULL;
FOR r_mld_kenmerken IN c_mld_kenmerken LOOP
-- Does the new (std)melding r_nextsteps.mld_stdmelding_key have this flexprop as well? THEN use it
BEGIN
--DBMS_OUTPUT.PUT_LINE ( 'SELECT kk.mld_kenmerk_key ..' || r_mld_kenmerken.mld_srtkenmerk_key || ' ' || r_nextsteps.mld_stdmelding_key);
benbezigmetsrtkenmerk := r_mld_kenmerken.mld_srtkenmerk_key;
benbezigmetgroep := r_mld_kenmerken.mld_kenmerk_groep;
benbezigmetomschrijving := r_mld_kenmerken.mld_kenmerk_omschrijving;
IF (benbezigmetsrtkenmerk <> wasbezigmetsrtkenmerk
OR (benbezigmetsrtkenmerk = wasbezigmetsrtkenmerk
AND benbezigmetgroep <> wasbezigmetgroep)
OR (benbezigmetsrtkenmerk = wasbezigmetsrtkenmerk
AND ((benbezigmetomschrijving IS NOT NULL AND wasbezigmetomschrijving IS NULL)
OR (benbezigmetomschrijving IS NULL AND wasbezigmetomschrijving IS NOT NULL)
OR (benbezigmetomschrijving IS NOT NULL AND wasbezigmetomschrijving IS NOT NULL AND benbezigmetomschrijving <> wasbezigmetomschrijving))))
THEN
wasbezigmetsrtkenmerk := benbezigmetsrtkenmerk;
wasbezigmetgroep := benbezigmetgroep;
wasbezigmetomschrijving := benbezigmetomschrijving;
--DBMS_OUTPUT.PUT_LINE ( 'EERSTE WAARDE VAN DIT KENMERK, van melding '||r_mld_kenmerken.mld_melding_key);
SELECT mld_kenmerk_key
INTO l_new_kenmerk_key
FROM (SELECT kk.mld_kenmerk_key
FROM mld_kenmerk kk,
mld_srtkenmerk sk
WHERE kk.mld_srtkenmerk_key = sk.mld_srtkenmerk_key
AND kk.mld_kenmerk_verwijder IS NULL
AND kk.mld_srtkenmerk_key = r_mld_kenmerken.mld_srtkenmerk_key
AND kk.mld_kenmerk_groep = r_mld_kenmerken.mld_kenmerk_groep
AND COALESCE(kk.mld_kenmerk_omschrijving, sk.mld_srtkenmerk_omschrijving) = r_mld_kenmerken.mld_kenmerk_omschrijving
AND kk.mld_kenmerk_niveau = 'S'
AND kk.mld_stdmelding_key = r_nextsteps.mld_stdmelding_key
UNION
SELECT kk.mld_kenmerk_key
FROM mld_kenmerk kk,
mld_srtkenmerk sk
WHERE kk.mld_srtkenmerk_key = sk.mld_srtkenmerk_key
AND kk.mld_kenmerk_verwijder IS NULL
AND kk.mld_srtkenmerk_key = r_mld_kenmerken.mld_srtkenmerk_key
AND kk.mld_kenmerk_groep = r_mld_kenmerken.mld_kenmerk_groep
AND COALESCE(kk.mld_kenmerk_omschrijving, sk.mld_srtkenmerk_omschrijving) = r_mld_kenmerken.mld_kenmerk_omschrijving
AND kk.mld_kenmerk_niveau = 'D'
AND kk.mld_stdmelding_key = r_nextsteps.mld_ins_discipline_key
UNION
SELECT kk.mld_kenmerk_key
FROM mld_kenmerk kk,
mld_srtkenmerk sk
WHERE kk.mld_srtkenmerk_key = sk.mld_srtkenmerk_key
AND kk.mld_kenmerk_verwijder IS NULL
AND kk.mld_srtkenmerk_key = r_mld_kenmerken.mld_srtkenmerk_key
AND kk.mld_kenmerk_groep = r_mld_kenmerken.mld_kenmerk_groep
AND COALESCE(kk.mld_kenmerk_omschrijving, sk.mld_srtkenmerk_omschrijving) = r_mld_kenmerken.mld_kenmerk_omschrijving
AND kk.mld_kenmerk_niveau = 'T'
AND kk.mld_stdmelding_key = r_nextsteps.ins_srtdiscipline_key
UNION
SELECT kk.mld_kenmerk_key
FROM mld_kenmerk kk,
mld_srtkenmerk sk
WHERE kk.mld_srtkenmerk_key = sk.mld_srtkenmerk_key
AND kk.mld_kenmerk_verwijder IS NULL
AND kk.mld_srtkenmerk_key = r_mld_kenmerken.mld_srtkenmerk_key
AND kk.mld_kenmerk_groep = r_mld_kenmerken.mld_kenmerk_groep
AND COALESCE(kk.mld_kenmerk_omschrijving, sk.mld_srtkenmerk_omschrijving) = r_mld_kenmerken.mld_kenmerk_omschrijving
AND kk.mld_kenmerk_niveau = 'A'
AND kk.mld_stdmelding_key IS NULL) x;
--DBMS_OUTPUT.PUT_LINE(r_mld_kenmerken.mld_melding_key||' '||r_mld_kenmerken.mld_srtkenmerk_key||' '||r_mld_kenmerken.mld_kenmerk_groep||'->'||l_new_melding_key||' '||l_new_kenmerk_key);
--DBMS_OUTPUT.PUT_LINE('ook aanwezig bij de nieuwe, dus insert');
--Controleer of dit kenmerk al is toegevoegd (meerdere voorliggende meldingen met zelfde kenmerk!)
INSERT INTO mld_kenmerkmelding (mld_melding_key,
mld_kenmerk_key,
mld_kenmerkmelding_waarde)
VALUES (l_new_melding_key,
l_new_kenmerk_key,
r_mld_kenmerken.mld_kenmerkmelding_waarde);
-- ELSE negeer dit record, we hebben deze al.
END IF;
EXCEPTION
WHEN NO_DATA_FOUND
THEN
NULL;
--DBMS_OUTPUT.PUT_LINE('not found');
WHEN TOO_MANY_ROWS
THEN
raise_application_error (
-20001,
'Soortkenmerk '
|| r_mld_kenmerken.mld_srtkenmerk_key
|| ' is op meerdere niveaus gedefinieerd');
--DBMS_OUTPUT.PUT_LINE('TOO MANY ROW');
END;
END LOOP;
END;
-- Vul nog lege flexkenmerken met een eventuele default waarde
IF fac.getsetting('mld_workflow_set_defaults') = 1
THEN
DECLARE
CURSOR def_mld_kenmerk
IS
SELECT k.mld_kenmerk_key, k.mld_kenmerk_default
FROM mld_kenmerk k
LEFT OUTER JOIN mld_kenmerkmelding km
ON ( k.mld_kenmerk_key = km.mld_kenmerk_key
AND km.mld_melding_key = l_new_melding_key)
, mld_srtkenmerk s
WHERE mld_kenmerk_verwijder IS NULL
AND k.mld_srtkenmerk_key = s.mld_srtkenmerk_key
AND s.mld_srtkenmerk_kenmerktype NOT IN ('F', 'E')
AND ((mld_kenmerk_niveau = 'A' AND mld_stdmelding_key IS NULL)
OR (mld_kenmerk_niveau = 'S' AND mld_stdmelding_key = r_nextsteps.mld_stdmelding_key)
OR (mld_kenmerk_niveau = 'D' AND mld_stdmelding_key = r_nextsteps.mld_ins_discipline_key)
OR (mld_kenmerk_niveau = 'T' AND mld_stdmelding_key = r_nextsteps.ins_srtdiscipline_key))
AND k.mld_kenmerk_default IS NOT NULL
AND km.mld_kenmerkmelding_waarde IS NULL;
this_mld_kenmerk def_mld_kenmerk%ROWTYPE;
BEGIN
FOR this_mld_kenmerk IN def_mld_kenmerk LOOP
BEGIN
INSERT INTO mld_kenmerkmelding (mld_melding_key,
mld_kenmerk_key,
mld_kenmerkmelding_waarde)
VALUES (l_new_melding_key,
this_mld_kenmerk.mld_kenmerk_key,
this_mld_kenmerk.mld_kenmerk_default);
END;
END LOOP;
END;
END IF;
-- Controleer of er automatisch een opdracht aangemaakt moet worden.
mld.mld_addautoorder(l_new_melding_key);
END IF; -- evaluatecondition
END IF;
FETCH c_nextsteps INTO r_nextsteps;
EXIT WHEN c_nextsteps%NOTFOUND;
END LOOP;
-- All nextsteps have been considered and started if the condition was true
-- If none of the conditions were true, no next step is started and the workflow dies
-- The previous step effectively was the/a last step so we should execute the corresponding
-- routine: close the root if all others (if any) are done as well.
IF l_nrstepsevaluatedtrue = 0
THEN
SELECT COUNT (mld_melding_key)
INTO tmp
FROM mld_melding
WHERE mld_melding_start_key = l_melding_start_key
AND mld_melding_status NOT IN (1, 5, 6)
AND mld_melding_key <> l_melding_start_key;
-- Als er geen lopende parallelle meldingen zijn dan sluit de root.
IF tmp = 0
THEN
DBMS_OUTPUT.put_line (
'Closing parent due to all false conditions: ' || l_melding_start_key);
mld.setmeldingstatus (l_melding_start_key, 5, NULL);
--ELSE
--DBMS_OUTPUT.PUT_LINE('no more steps, but still ' || tmp || ' open calls in workflow');
END IF;
END IF;
CLOSE c_nextsteps;
END IF;
END;
END mld_nextworkflowstep;
-- Bereken van de melding het object met de laagste uitvoertijd.
FUNCTION getlowestobjectuitvoer (p_melding_key IN NUMBER)
RETURN NUMBER
AS
v_ins_key_min_uitvoertijd NUMBER;
BEGIN
SELECT MAX (d.ins_deel_key) ins_deel_key
INTO v_ins_key_min_uitvoertijd
FROM ins_deel d,
mld_melding_object m
WHERE m.mld_melding_key = p_melding_key
AND d.ins_deel_key = m.ins_deel_key
AND (CASE
WHEN d.ins_deel_t_uitvoertijd.eenheid = 'U'
THEN d.ins_deel_t_uitvoertijd.tijdsduur / 24
ELSE d.ins_deel_t_uitvoertijd.tijdsduur
END) = (SELECT MIN (CASE
WHEN d1.ins_deel_t_uitvoertijd.eenheid = 'U'
THEN d1.ins_deel_t_uitvoertijd.tijdsduur / 24
ELSE d1.ins_deel_t_uitvoertijd.tijdsduur
END)
FROM ins_deel d1,
mld_melding_object m1
WHERE m1.mld_melding_key = p_melding_key
AND d1.ins_deel_key = m1.ins_deel_key);
RETURN v_ins_key_min_uitvoertijd;
END;
-- Dit is de tijd waarop afgerekend gaat worden. Respijt wordt er afgetrokken
FUNCTION getactualuitvoer (p_melding_key IN NUMBER)
RETURN MLD_T_UITVOERTIJD
AS
v_ins_key_min_uitvoertijd NUMBER;
v_actual_uitvoertijd_object mld_stdmelding.mld_stdmelding_t_uitvoertijd%TYPE := MLD_T_UITVOERTIJD(NULL, NULL); -- constructor initialisatie;
BEGIN
-- Bepaal van de melding het object met de laagste uitvoertijd.
v_ins_key_min_uitvoertijd := getlowestobjectuitvoer(p_melding_key);
SELECT mld.getactualuitvoer(m.mld_melding_datum,
COALESCE(fac.gettrackingdate('MLDAFM', m.mld_melding_key), fac.gettrackingdate('MLDREJ', m.mld_melding_key), SYSDATE),
m.mld_stdmelding_key,
m.mld_melding_spoed,
m.mld_alg_onroerendgoed_keys,
v_ins_key_min_uitvoertijd,
m.mld_melding_t_uitvoertijd.eenheid
)
INTO v_actual_uitvoertijd_object
FROM mld_melding m
WHERE mld_melding_key = p_melding_key;
RETURN v_actual_uitvoertijd_object;
END;
FUNCTION getactualuitvoer (startdate IN DATE,
enddate IN DATE,
stdm_key IN NUMBER,
prio IN NUMBER,
alg_key IN NUMBER, -- Altijd gebouw of hoger, locatie niet ondersteund
ins_key IN NUMBER, -- Object met de laagste uitvoertijd
eenheid IN VARCHAR2 DEFAULT NULL
)
RETURN MLD_T_UITVOERTIJD
AS
v_actual_uitvoertijd_object mld_stdmelding.mld_stdmelding_t_uitvoertijd%TYPE := MLD_T_UITVOERTIJD(NULL, NULL); -- constructor initialisatie;
v_uitvoertijdtype VARCHAR2(5);
v_mld_stdmelding_regime mld_stdmelding.mld_stdmelding_regime%TYPE;
v_beginuur alg_gebouw.alg_gebouw_beginuur%TYPE;
v_einduur alg_gebouw.alg_gebouw_einduur%TYPE;
v_werkdagen alg_gebouw.alg_gebouw_werkdagen%TYPE;
BEGIN
getSLAparams(stdm_key, prio, alg_key, ins_key,
v_mld_stdmelding_regime, v_actual_uitvoertijd_object, v_beginuur, v_einduur, v_werkdagen);
IF COALESCE(eenheid, v_actual_uitvoertijd_object.eenheid) = 'D'
THEN
v_uitvoertijdtype := 'DAGEN';
ELSE
v_uitvoertijdtype := 'UREN';
END IF;
-- Als bij Openingstijden geen ruimte/gebouwopeningstijden zijn gevonden dan terugvallen op Kantoortijden.
IF v_mld_stdmelding_regime = 1 OR (v_mld_stdmelding_regime = 2 AND (v_beginuur = -1 OR v_einduur = -1)) -- Kantoortijden: als in 5.1.2
THEN
v_actual_uitvoertijd_object :=
FAC.datumtijdnaaruitvoertijd (startdate, enddate, v_uitvoertijdtype);
ELSIF v_mld_stdmelding_regime = 2 -- Openingstijden: gebruik ruimte/gebouwopeningstijden
THEN
v_actual_uitvoertijd_object :=
FAC.datumtijdnaaruitvoertijd (startdate,
enddate,
v_uitvoertijdtype,
v_beginuur,
v_einduur,
v_werkdagen); -- Mode=0/1 resp. alle dagen/alleen werkdagen!
ELSIF v_mld_stdmelding_regime = 3 -- 24/7: negeert weekenden of vrije dagen
THEN
v_actual_uitvoertijd_object :=
FAC.datumtijdnaaruitvoertijd (startdate,
enddate,
v_uitvoertijdtype,
NULL, -- Don't care
NULL, -- Don't care
2); -- Mode=2 => 24/7
END IF;
-- Een negatieve actuele uitvoertijd niet toestaan. Minimale waarde is 0.
IF v_actual_uitvoertijd_object.tijdsduur < 0
THEN
v_actual_uitvoertijd_object.tijdsduur := 0;
END IF;
RETURN v_actual_uitvoertijd_object;
END;
FUNCTION uitvoertijd_to_char (uitvoertijd IN MLD_T_UITVOERTIJD)
RETURN VARCHAR
AS BEGIN
IF uitvoertijd IS NULL THEN
RETURN NULL;
END IF;
RETURN '(' || uitvoertijd.tijdsduur || '; ' || uitvoertijd.eenheid || ')';
END;
-- bereken de SLA-einddatum gegeven onderstaande info
FUNCTION geteinddatum (startdate IN DATE,
stdm_key IN NUMBER,
prio IN NUMBER,
alg_key IN NUMBER, -- Altijd gebouw of hoger, locatie niet ondersteund
ins_key IN NUMBER, -- Object met de laagste uitvoertijd
uitvoertijd_object IN MLD_T_UITVOERTIJD DEFAULT MLD_T_UITVOERTIJD(NULL, NULL)) -- Als meegegeven dan wordt dit genomen als norm
RETURN DATE -- Handig voor (bevroren) mld_melding_uitvoertijd + respijt
AS
v_einddatum DATE;
v_mld_stdmelding_regime mld_stdmelding.mld_stdmelding_regime%TYPE;
v_uitvoertijd_object mld_stdmelding.mld_stdmelding_t_uitvoertijd%TYPE := MLD_T_UITVOERTIJD(NULL, NULL); -- contructor initialisatie;
v_uitvoertijdtype VARCHAR2(5);
v_beginuur alg_gebouw.alg_gebouw_beginuur%TYPE;
v_einduur alg_gebouw.alg_gebouw_einduur%TYPE;
v_werkdagen NUMBER;
BEGIN
getSLAparams(stdm_key, prio, alg_key, ins_key,
v_mld_stdmelding_regime, v_uitvoertijd_object, v_beginuur, v_einduur, v_werkdagen);
IF uitvoertijd_object.eenheid IS NOT NULL
THEN
v_uitvoertijd_object := uitvoertijd_object;
END IF;
IF v_uitvoertijd_object.eenheid = 'D'
THEN
v_uitvoertijdtype := 'DAGEN';
ELSE
v_uitvoertijdtype := 'UREN';
END IF;
-- Als bij openingstijden geen ruimte/gebouwopeningstijden zijn gevonden dan terugvallen op kantoortijden.
IF v_mld_stdmelding_regime = 1 OR (v_mld_stdmelding_regime = 2 AND (v_beginuur = -1 OR v_einduur = -1)) -- kantoortijden, als in 5.1.2
THEN
v_einddatum :=
FAC.DatumTijdPlusUitvoerTijd (startdate,
v_uitvoertijd_object.tijdsduur,
v_uitvoertijdtype);
ELSIF v_mld_stdmelding_regime = 2 -- Openingstijden: gebruik ruimte/gebouwopeningstijden er bij
THEN
v_einddatum :=
FAC.datumtijdplusuitvoertijd (startdate,
v_uitvoertijd_object.tijdsduur,
v_uitvoertijdtype,
v_beginuur,
v_einduur,
v_werkdagen); -- Mode=0/1 resp. alle dagen/alleen werkdagen!
ELSIF v_mld_stdmelding_regime = 3 -- 24/7, negeert weekenden of vrije dagen
THEN
v_einddatum :=
FAC.datumtijdplusuitvoertijd (startdate,
v_uitvoertijd_object.tijdsduur,
v_uitvoertijdtype,
NULL, -- Don't care
NULL, -- Don't care
2); -- Mode=2 => 24/7
END IF;
RETURN v_einddatum;
END;
FUNCTION geteinddatum (p_melding_key IN NUMBER,
p_uitvoertijd_object IN MLD_T_UITVOERTIJD DEFAULT MLD_T_UITVOERTIJD(NULL, NULL), -- Als meegegeven dan wordt dit genomen als norm
p_startdate IN DATE DEFAULT NULL) -- Bereken einddatum met startdatum (voor opdrachten en meldingen verschillend)
RETURN DATE
AS
v_ins_key_min_uitvoertijd NUMBER := NULL;
v_einddatum DATE;
BEGIN
-- Als p_uitvoertijd_object meegegeven is dan is object met de laagste uitvoertijd niet meer van belang
IF p_uitvoertijd_object.eenheid IS NULL
THEN
-- Bepaal van de melding het object met de laagste uitvoertijd.
v_ins_key_min_uitvoertijd := getlowestobjectuitvoer(p_melding_key);
END IF;
SELECT mld.geteinddatum(COALESCE(p_startdate, m.mld_melding_datum),
m.mld_stdmelding_key,
m.mld_melding_spoed,
m.mld_alg_onroerendgoed_keys,
v_ins_key_min_uitvoertijd, -- Object met de laagste uitvoertijd
p_uitvoertijd_object
)
INTO v_einddatum
FROM mld_melding m
WHERE mld_melding_key = p_melding_key;
RETURN v_einddatum;
END;
-- Bereken de standaard uitvoertijd
FUNCTION getstduitvoer (stdm_key IN NUMBER,
prio IN NUMBER,
alg_key IN NUMBER, -- Altijd gebouw of hoger, locatie niet ondersteund
ins_key IN NUMBER) -- Object met de laagste uitvoertijd
RETURN MLD_T_UITVOERTIJD
AS
v_uitvoertijd_object mld_stdmelding.mld_stdmelding_t_uitvoertijd%TYPE := MLD_T_UITVOERTIJD(NULL, NULL); -- contructor initialisatie
v_mld_stdmelding_regime mld_stdmelding.mld_stdmelding_regime%TYPE;
v_beginuur alg_gebouw.alg_gebouw_beginuur%TYPE;
v_einduur alg_gebouw.alg_gebouw_einduur%TYPE;
v_werkdagen NUMBER;
BEGIN
getSLAparams(stdm_key, prio, alg_key, ins_key,
v_mld_stdmelding_regime, v_uitvoertijd_object, v_beginuur, v_einduur, v_werkdagen);
RETURN v_uitvoertijd_object;
END;
-- Bereken de standaard uitvoertijd
FUNCTION getstduitvoer (p_melding_key IN NUMBER)
RETURN MLD_T_UITVOERTIJD
AS
v_uitvoertijd_object mld_stdmelding.mld_stdmelding_t_uitvoertijd%TYPE := MLD_T_UITVOERTIJD(NULL, NULL); -- contructor initialisatie
v_ins_key_min_uitvoertijd NUMBER;
v_ins_key_min_uitvoertijd_eenh NUMBER;
v_std_uitvoertijd NUMBER;
v_std_uitvoertijd_eenheid NUMBER;
BEGIN
-- Bepaal van de melding het object met de laagste uitvoertijd.
v_ins_key_min_uitvoertijd := getlowestobjectuitvoer(p_melding_key);
SELECT mld.getstduitvoer(m.mld_stdmelding_key,
m.mld_melding_spoed,
m.mld_alg_onroerendgoed_keys,
v_ins_key_min_uitvoertijd
)
INTO v_uitvoertijd_object
FROM mld_melding m
WHERE mld_melding_key = p_melding_key;
RETURN v_uitvoertijd_object;
END;
PROCEDURE getSLAparams (stdm_key IN NUMBER,
prio IN NUMBER,
alg_key IN NUMBER, -- Altijd gebouw of hoger, locatie niet ondersteund
ins_key IN NUMBER, -- Object met de laagste uitvoertijd
v_mld_stdmelding_regime OUT NUMBER,
v_uitvoertijd_object OUT MLD_T_UITVOERTIJD,
v_beginuur OUT NUMBER,
v_einduur OUT NUMBER,
v_werkdagen OUT NUMBER
)
AS
v_uitvoertijd_object_s mld_stdmelding.mld_stdmelding_t_uitvoertijd%TYPE := MLD_T_UITVOERTIJD(NULL, NULL); -- contructor initialisatie
v_mld_stdmelding_afhankelijk mld_stdmelding.mld_stdmelding_afhankelijk%TYPE;
l_alg_type VARCHAR2(1);
l_terreinsector_key alg_terreinsector.alg_terreinsector_key%TYPE;
l_gebouw_key alg_gebouw.alg_gebouw_key%TYPE;
l_ruimte_key alg_ruimte.alg_ruimte_key%TYPE;
l_insdeel_uitvoertijd_object ins_deel.ins_deel_t_uitvoertijd%TYPE := MLD_T_UITVOERTIJD(NULL, NULL); -- contructor initialisatie
l_srtruimte_uitvoertijd_object alg_srtruimte.alg_srtruimte_t_uitvoertijd%TYPE := MLD_T_UITVOERTIJD(NULL, NULL); -- contructor initialisatie
l_srtgebouw_uitvoertijd_object alg_srtgebouw.alg_srtgebouw_t_uitvoertijd%TYPE := MLD_T_UITVOERTIJD(NULL, NULL); -- contructor initialisatie
l_srtterrein_uitvoertijd_object alg_srtterreinsector.alg_srtterreinsec_t_uitvtijd%TYPE := MLD_T_UITVOERTIJD(NULL, NULL); -- contructor initialisatie
l_mldsrtruimte_uitvtijd_object mld_stdmsrtruimte.mld_stdmsrtruimte_t_uitvtijd%TYPE := MLD_T_UITVOERTIJD(NULL, NULL); -- contructor initialisatie
l_mldsrtgebouw_uitvtijd_object mld_stdmsrtgebouw.mld_stdmsrtgebouw_t_uitvtijd%TYPE := MLD_T_UITVOERTIJD(NULL, NULL); -- contructor initialisatie
l_mldsrtterrein_uitvtijd_object mld_stdmsrtterrein.mld_stdmsrtterrein_t_uitvtijd%TYPE := MLD_T_UITVOERTIJD(NULL, NULL); -- contructor initialisatie
BEGIN
SELECT mld_stdmelding_regime,
COALESCE(CASE prio
WHEN 1 THEN mld_stdmelding_t_uitvtijd_pr1
WHEN 2 THEN mld_stdmelding_t_uitvtijd_pr2
WHEN 4 THEN mld_stdmelding_t_uitvtijd_pr4
ELSE mld_stdmelding_t_uitvoertijd
END, mld_stdmelding_t_uitvoertijd), -- gegarandeerd gevuld
mld_stdmelding_t_uitvoertijd, -- standaard uitvoertijd
mld_stdmelding_afhankelijk
INTO v_mld_stdmelding_regime,
v_uitvoertijd_object,
v_uitvoertijd_object_s,
v_mld_stdmelding_afhankelijk
FROM mld_stdmelding msm
WHERE msm.mld_stdmelding_key = stdm_key;
IF v_mld_stdmelding_afhankelijk = 1 AND ins_key IS NOT NULL
THEN
SELECT d.ins_deel_t_uitvoertijd
INTO l_insdeel_uitvoertijd_object
FROM ins_deel d
WHERE d.ins_deel_key = ins_key;
v_uitvoertijd_object.tijdsduur := COALESCE(l_insdeel_uitvoertijd_object.tijdsduur, v_uitvoertijd_object_s.tijdsduur);
IF l_insdeel_uitvoertijd_object.tijdsduur IS NOT NULL
THEN
v_uitvoertijd_object.eenheid := l_insdeel_uitvoertijd_object.eenheid;
ELSE
v_uitvoertijd_object.eenheid := v_uitvoertijd_object_s.eenheid;
END IF;
END IF;
IF v_mld_stdmelding_afhankelijk = 1 AND l_insdeel_uitvoertijd_object.tijdsduur IS NULL AND alg_key IS NOT NULL
THEN
-- Als alg_srtruimte_uitvoertijd geen waarde heeft, dan terugvallen op standaard uitvoertijd die altijd een waarde heeft
SELECT alg_type,
alg_terreinsector_key,
alg_gebouw_key,
alg_ruimte_key
INTO l_alg_type,
l_terreinsector_key,
l_gebouw_key,
l_ruimte_key
FROM alg_v_onroerendgoed
WHERE alg_onroerendgoed_keys = alg_key;
IF l_alg_type = 'T'
THEN
BEGIN
SELECT st.alg_srtterreinsec_t_uitvtijd,
sst.mld_stdmsrtterrein_t_uitvtijd,
COALESCE(sst.mld_stdmsrtterrein_regime, v_mld_stdmelding_regime) regime -- optioneel nog srtterreinsector-afhankelijk afwijkend regime.
INTO l_srtterrein_uitvoertijd_object,
l_mldsrtterrein_uitvtijd_object,
v_mld_stdmelding_regime
FROM alg_terreinsector t,
alg_srtterreinsector st,
mld_stdmsrtterrein sst
WHERE t.alg_srtterreinsector_key = st.alg_srtterreinsector_key(+)
AND t.alg_srtterreinsector_key = sst.alg_srtterreinsector_key(+)
AND sst.mld_stdmelding_key(+) = stdm_key
AND t.alg_terreinsector_key = l_terreinsector_key;
EXCEPTION
WHEN NO_DATA_FOUND
THEN NULL;
END;
ELSE
BEGIN
SELECT alg_srtgebouw_t_uitvoertijd,
ssg.mld_stdmsrtgebouw_t_uitvtijd,
COALESCE(ssg.mld_stdmsrtgebouw_regime, v_mld_stdmelding_regime) regime -- optioneel nog srtgebouw-afhankelijk afwijkend regime.
INTO l_srtgebouw_uitvoertijd_object,
l_mldsrtgebouw_uitvtijd_object,
v_mld_stdmelding_regime
FROM alg_gebouw g,
alg_srtgebouw sg,
mld_stdmsrtgebouw ssg
WHERE g.alg_srtgebouw_key = sg.alg_srtgebouw_key(+)
AND g.alg_srtgebouw_key = ssg.alg_srtgebouw_key(+)
AND ssg.mld_stdmelding_key(+) = stdm_key
AND g.alg_gebouw_key = l_gebouw_key;
EXCEPTION
WHEN NO_DATA_FOUND
THEN NULL;
END;
IF l_alg_type = 'R'
THEN
BEGIN
SELECT sr.alg_srtruimte_t_uitvoertijd,
ssr.mld_stdmsrtruimte_t_uitvtijd,
COALESCE(ssr.mld_stdmsrtruimte_regime, v_mld_stdmelding_regime) -- optioneel nog srtruimte-afhankelijk afwijkend regime.
INTO l_srtruimte_uitvoertijd_object,
l_mldsrtruimte_uitvtijd_object,
v_mld_stdmelding_regime
FROM alg_ruimte r,
alg_srtruimte sr,
mld_stdmsrtruimte ssr
WHERE r.alg_srtruimte_key = sr.alg_srtruimte_key(+)
AND r.alg_srtruimte_key = ssr.alg_srtruimte_key(+)
AND ssr.mld_stdmelding_key(+) = stdm_key
AND r.alg_ruimte_key = l_ruimte_key;
EXCEPTION
WHEN NO_DATA_FOUND
THEN NULL;
END;
END IF;
END IF;
-- Uitvoertijd van de srtruimte, srtgebouw of srtterreinsector nemen.
-- Als alg_srtruimte_t_uitvoertijd, alg_srtgebouw_t_uitvoertijd en alg_srtterreinsec_t_uitvtijd geen waarden hebben, dan terugvallen op standaard uitvoertijd die altijd een waarde heeft.
IF l_alg_type = 'T'
THEN
v_uitvoertijd_object.tijdsduur := COALESCE(l_mldsrtterrein_uitvtijd_object.tijdsduur, l_srtterrein_uitvoertijd_object.tijdsduur, v_uitvoertijd_object_s.tijdsduur);
ELSE
v_uitvoertijd_object.tijdsduur := COALESCE(l_mldsrtruimte_uitvtijd_object.tijdsduur, l_srtruimte_uitvoertijd_object.tijdsduur, -- eerst ruimte
l_mldsrtgebouw_uitvtijd_object.tijdsduur, l_srtgebouw_uitvoertijd_object.tijdsduur, -- dan gebouw
v_uitvoertijd_object_s.tijdsduur); -- dan standaard.
END IF;
IF l_mldsrtruimte_uitvtijd_object.tijdsduur IS NOT NULL
THEN
v_uitvoertijd_object.eenheid := l_mldsrtruimte_uitvtijd_object.eenheid;
ELSIF l_srtruimte_uitvoertijd_object.tijdsduur IS NOT NULL
THEN
v_uitvoertijd_object.eenheid := l_srtruimte_uitvoertijd_object.eenheid;
ELSIF l_mldsrtgebouw_uitvtijd_object.tijdsduur IS NOT NULL
THEN
v_uitvoertijd_object.eenheid := l_mldsrtgebouw_uitvtijd_object.eenheid;
ELSIF l_srtgebouw_uitvoertijd_object.tijdsduur IS NOT NULL
THEN
v_uitvoertijd_object.eenheid := l_srtgebouw_uitvoertijd_object.eenheid;
ELSE
v_uitvoertijd_object.eenheid := v_uitvoertijd_object_s.eenheid;
END IF;
END IF;
IF alg_key IS NULL AND v_mld_stdmelding_regime = 2
THEN
v_mld_stdmelding_regime := 1; -- dan terugvallen op algemene kantooruren
END IF;
IF v_mld_stdmelding_regime = 2 -- Openingstijden: zoek ruimte/gebouwopeningstijden er bij
THEN
SELECT MAX(alg_ruimte_key)
INTO l_ruimte_key
FROM alg_ruimte r
WHERE r.alg_ruimte_key = alg_key;
-- Minstens <20><>n van beide keys is gedefinieerd, zeker weten
IF l_ruimte_key IS NOT NULL
THEN
-- de tijden van de ruimte of anders het gebouw gelden
SELECT COALESCE (alg_ruimte_beginuur, alg_gebouw_beginuur, -1),
COALESCE (alg_ruimte_einduur, alg_gebouw_einduur, -1),
COALESCE (alg_ruimte_werkdagen, alg_gebouw_werkdagen)
INTO v_beginuur, v_einduur, v_werkdagen
FROM alg_ruimte r, alg_verdieping v, alg_gebouw g
WHERE r.alg_verdieping_key = v.alg_verdieping_key
AND v.alg_gebouw_key = g.alg_gebouw_key
AND r.alg_ruimte_key = l_ruimte_key;
ELSE
-- alg_key zal een gebouw, verdieping of terrein zijn.
-- de tijden van het gebouw gelden of uren opleveren.
SELECT beginuur,
einduur,
werkdagen
INTO v_beginuur,
v_einduur,
v_werkdagen
FROM (SELECT COALESCE(alg_gebouw_beginuur, -1) beginuur,
COALESCE(alg_gebouw_einduur, -1) einduur,
alg_gebouw_werkdagen werkdagen
FROM alg_gebouw g,
alg_v_allonroerendgoed aag
WHERE g.alg_gebouw_key = aag.alg_gebouw_key
AND aag.alg_onroerendgoed_keys = alg_key
UNION
SELECT -1 beginuur,
-1 einduur,
1 werkdagen
FROM alg_terreinsector t,
alg_v_allonroerendgoed aag
WHERE t.alg_terreinsector_key = aag.alg_terreinsector_key
AND aag.alg_onroerendgoed_keys = alg_key);
END IF;
END IF;
RETURN;
END;
FUNCTION getacceptdatum (startdate IN DATE, stdm_key IN NUMBER, alg_key IN NUMBER, p_prio IN NUMBER DEFAULT 3)
RETURN DATE
IS
l_accepttijd_object mld_stdmelding.mld_stdmelding_t_accepttijd%TYPE := MLD_T_UITVOERTIJD(NULL, NULL); -- contructor initialisatie;
l_accepttijd_normaal mld_stdmelding.mld_stdmelding_t_accepttijd%TYPE := MLD_T_UITVOERTIJD(NULL, NULL); -- contructor initialisatie;
l_stdmelding_regime mld_stdmelding.mld_stdmelding_regime%TYPE;
l_ruimte_key alg_ruimte.alg_ruimte_key%TYPE;
l_beginuur alg_gebouw.alg_gebouw_beginuur%TYPE;
l_einduur alg_gebouw.alg_gebouw_einduur%TYPE;
l_werkdagen NUMBER;
l_uitvoertijdtype VARCHAR2(5);
BEGIN
SELECT DECODE (p_prio,
1, mld_stdmelding_t_accept_pr1,
2, mld_stdmelding_t_accept_pr2,
3, mld_stdmelding_t_accepttijd,
4, mld_stdmelding_t_accept_pr4,
mld_stdmelding_t_accepttijd),
mld_stdmelding_t_accepttijd,
mld_stdmelding_regime
INTO l_accepttijd_object, l_accepttijd_normaal, l_stdmelding_regime
FROM mld_stdmelding
WHERE mld_stdmelding_key = stdm_key;
-- Als je geen afwijkende acceptatietijd per prio hebt, dan is het die van Normaal
IF p_prio <> 3 AND l_accepttijd_object.tijdsduur IS NULL
THEN
l_accepttijd_object := l_accepttijd_normaal;
END IF;
-- mld_stdmelding_regime: 1) Kantoortijden regime
-- 2) Openingstijden regime
-- 3) 24/7 regime (negeert weekenden of vrije dagen)
-- De functie fac.datumtijdplusuitvoertijd kan rekenen met zowel dagen als uren
IF l_accepttijd_object.eenheid = 'D'
THEN
l_uitvoertijdtype := 'DAGEN';
ELSE
l_uitvoertijdtype := 'UREN';
END IF;
-- Hier wordt verder gehandeld obv regime. Ik zou verwachten dat mld_stdmelding_afhankelijk mede bepalend is
-- Regime kan nu per srtruimte afwijken dus moeten we daar eerst naar toe. De rest van de flow kan dan intact blijven.
IF (alg_key IS NOT NULL)
THEN
-- Als het een ruimte-key is maken we dat hier expliciet
SELECT MAX(alg_ruimte_key)
INTO l_ruimte_key
FROM alg_ruimte r
WHERE r.alg_ruimte_key = alg_key;
-- Dan kunnen we met de srtruimte evt afwijkend regime bepalen
IF l_ruimte_key IS NOT NULL
THEN
SELECT COALESCE(ssr.mld_stdmsrtruimte_regime, l_stdmelding_regime)
INTO l_stdmelding_regime
FROM alg_ruimte r, mld_stdmsrtruimte ssr
WHERE r.alg_srtruimte_key = ssr.alg_srtruimte_key(+)
AND ssr.mld_stdmelding_key(+) = stdm_key
AND r.alg_ruimte_key = l_ruimte_key;
END IF;
END IF;
-- nu weten we het geldende regime
IF (l_stdmelding_regime = 1) OR (alg_key IS NULL AND l_stdmelding_regime = 2) -- Kantoortijdenregime of hierop terugvallen
THEN
RETURN fac.datumtijdplusuitvoertijd (startdate, l_accepttijd_object.tijdsduur, l_uitvoertijdtype);
END IF;
IF l_stdmelding_regime = 2 -- Openingstijden: zoek ruimte/gebouwopeningstijden er bij
THEN
-- Minstens <20><>n van beide keys is gedefinieerd, zeker weten
IF l_ruimte_key IS NOT NULL
THEN
-- de tijden van de ruimte of anders het gebouw gelden
SELECT COALESCE (alg_ruimte_beginuur, alg_gebouw_beginuur, 0),
COALESCE (alg_ruimte_einduur, alg_gebouw_einduur, 24),
COALESCE (alg_ruimte_werkdagen, alg_gebouw_werkdagen)
INTO l_beginuur, l_einduur, l_werkdagen
FROM alg_ruimte r, alg_verdieping v, alg_gebouw g
WHERE r.alg_verdieping_key = v.alg_verdieping_key
AND v.alg_gebouw_key = g.alg_gebouw_key
AND r.alg_ruimte_key = l_ruimte_key;
ELSE
-- alg_key zal een gebouw, verdieping of terrein zijn.
-- de tijden van het gebouw gelden of 24 per dag alleen op werkdagen.
SELECT beginuur,
einduur,
werkdagen
INTO l_beginuur,
l_einduur,
l_werkdagen
FROM (SELECT COALESCE(alg_gebouw_beginuur, 0) beginuur,
COALESCE(alg_gebouw_einduur, 24) einduur,
alg_gebouw_werkdagen werkdagen
FROM alg_gebouw g,
alg_v_allonroerendgoed aag
WHERE g.alg_gebouw_key = aag.alg_gebouw_key
AND aag.alg_onroerendgoed_keys = alg_key
UNION
SELECT 0 beginuur,
24 einduur,
1 werkdagen
FROM alg_terreinsector t,
alg_v_allonroerendgoed aag
WHERE t.alg_terreinsector_key = aag.alg_terreinsector_key
AND aag.alg_onroerendgoed_keys = alg_key);
END IF;
RETURN FAC.datumtijdplusuitvoertijd (startdate,
l_accepttijd_object.tijdsduur,
l_uitvoertijdtype,
l_beginuur,
l_einduur,
l_werkdagen); -- Mode=0/1 resp. alle dagen/alleen werkdagen!
END IF;
IF l_stdmelding_regime = 3 -- 24/7, negeert weekenden of vrije dagen
THEN
RETURN FAC.datumtijdplusuitvoertijd (startdate,
l_accepttijd_object.tijdsduur,
l_accepttijd_object.eenheid,
NULL, -- Don't care
NULL, -- Don't care
2); -- Mode=2 => 24/7
END IF;
END;
FUNCTION getnettotijdsbesteding (p_opdr_key IN NUMBER, p_prs_key IN NUMBER DEFAULT NULL) RETURN NUMBER
AS
l_netto_tijd NUMBER;
l_fsn_code_last fac_srtnotificatie.fac_srtnotificatie_code%TYPE;
l_ft_datum_last fac_tracking.fac_tracking_datum%TYPE;
l_ft_perslid_key fac_tracking.prs_perslid_key%TYPE;
l_mld_typeopdr_sequential mld_typeopdr.mld_typeopdr_sequential%TYPE;
CURSOR c_tracking
IS
SELECT st.fac_srtnotificatie_code,
t.fac_tracking_datum,
t.prs_perslid_key
FROM fac_tracking t,
fac_srtnotificatie st
WHERE t.fac_srtnotificatie_key = st.fac_srtnotificatie_key
AND st.fac_srtnotificatie_code IN ('ORDACP', 'ORDHLT', 'ORDRSM', 'ORDAFM')
AND fac_tracking_refkey = p_opdr_key
ORDER BY fac_tracking_datum;
BEGIN
l_netto_tijd := 0;
l_fsn_code_last := NULL;
l_ft_datum_last := NULL;
l_ft_perslid_key := NULL;
SELECT mto.mld_typeopdr_sequential
INTO l_mld_typeopdr_sequential
FROM mld_opdr o,
mld_typeopdr mto
WHERE o.mld_typeopdr_key = mto.mld_typeopdr_key
AND o.mld_opdr_key = p_opdr_key;
FOR r IN c_tracking
LOOP
-- Alleen als 'ORDAFM' of 'ORDHLT' getrackt is wordt er eventueel tijd bij de nettotijd opgeteld.
-- Dan moet de vorige tracking wel 'ORDACP' of 'ORDRSM' zijn.
-- Uitgezonderd als alleen de periode 'ORDACP-ORDAFM' is getrackt en "Onderbroken start" (mld_typeopdr.mld_typeopdr_sequential) aan staat.
IF (r.fac_srtnotificatie_code = 'ORDAFM' OR r.fac_srtnotificatie_code = 'ORDHLT') AND
(l_fsn_code_last = 'ORDACP' OR l_fsn_code_last = 'ORDRSM') AND
l_ft_perslid_key = p_prs_key AND
(l_fsn_code_last != 'ORDACP' OR r.fac_srtnotificatie_code != 'ORDAFM' OR BITAND(l_mld_typeopdr_sequential, 4) = 0)
THEN
l_netto_tijd := l_netto_tijd + (r.fac_tracking_datum - l_ft_datum_last);
END IF;
l_fsn_code_last := r.fac_srtnotificatie_code;
l_ft_datum_last := r.fac_tracking_datum;
l_ft_perslid_key := r.prs_perslid_key;
END LOOP;
-- Als de opdracht nog actief is en niet op hold staat, moet er nog tijd tot nu (SYSDATE) bij opgeteld worden.
-- Uitgezonderd als 'ORDACP' als laatste is getrackt en "Onderbroken start" (mld_typeopdr.mld_typeopdr_sequential) aan staat.
IF (l_fsn_code_last = 'ORDACP' OR l_fsn_code_last = 'ORDRSM') AND
l_ft_perslid_key = p_prs_key AND
(l_fsn_code_last != 'ORDACP' OR BITAND(l_mld_typeopdr_sequential, 4) = 0)
THEN
l_netto_tijd := l_netto_tijd + (SYSDATE - l_ft_datum_last);
END IF;
RETURN l_netto_tijd;
END;
FUNCTION BepaalOpdrMeldingVolgnr(p_melding_key IN NUMBER) RETURN NUMBER IS
ReturnVal NUMBER;
BEGIN
SELECT COALESCE(MAX(mld_opdr_bedrijfopdr_volgnr),0) + 1
INTO ReturnVal
FROM mld_opdr
WHERE mld_melding_key = p_melding_key;
RETURN ReturnVal;
END;
FUNCTION BepaalOpdrContractVolgnr(p_contract_key IN NUMBER) RETURN NUMBER IS
ReturnVal NUMBER;
BEGIN
SELECT COALESCE(MAX(mld_opdr_bedrijfopdr_volgnr),0) + 1
INTO ReturnVal
FROM mld_opdr
WHERE cnt_contract_key = p_contract_key;
RETURN ReturnVal;
END;
FUNCTION mldsprintf (ps IN VARCHAR2, p_melding_key IN NUMBER)
RETURN VARCHAR2
IS
s VARCHAR2 (2048 CHAR);
varstdmld mld_stdmelding.mld_stdmelding_omschrijving%TYPE;
vardisc ins_tab_discipline.ins_discipline_omschrijving%TYPE;
varsrtdisc ins_srtdiscipline.ins_srtdiscipline_prefix%TYPE;
varonroerendgoedkeys mld_melding.mld_alg_onroerendgoed_keys%TYPE;
varplaats VARCHAR2 (4000); -- Ook groot genoeg voor locatieomschrijving
varonderwerp mld_melding.mld_melding_onderwerp%TYPE;
varspoed mld_melding.mld_melding_spoed%TYPE;
varextnr mld_melding.mld_melding_externnr%TYPE;
BEGIN
s := ps;
-- We do support substitution of placeholders in the messages
-- ##DISC## = ins_discipline_omschrijving
-- ##STDMLD## = mld_stdmelding_omschrijving
-- ##KEY## = ins_srtdiscipline_prefix+key
-- ##PLAATS## = plaatsaanduidig van plaats service
-- ##SUBJECT## = mld_melding_onderwerp
-- ##SPOED## = 'SPOED' indien spoed, anders ''
-- ##EXTNR## = extern nummer
IF INSTR (s, '#') > 0
THEN
SELECT lcl.x ('mld_stdmelding_omschrijving',
stdm.mld_stdmelding_key,
stdm.mld_stdmelding_omschrijving),
lcl.x ('ins_discipline_omschrijving',
d.ins_discipline_key,
d.ins_discipline_omschrijving),
sd.ins_srtdiscipline_prefix,
m.mld_alg_onroerendgoed_keys,
m.mld_melding_spoed,
m.mld_melding_onderwerp,
m.mld_melding_externnr
INTO varstdmld,
vardisc,
varsrtdisc,
varonroerendgoedkeys,
varspoed,
varonderwerp,
varextnr
FROM mld_stdmelding stdm,
ins_tab_discipline d,
ins_srtdiscipline sd,
mld_melding m
WHERE d.ins_srtdiscipline_key = sd.ins_srtdiscipline_key
AND stdm.mld_ins_discipline_key = d.ins_discipline_key
AND stdm.mld_stdmelding_key = m.mld_stdmelding_key
AND m.mld_melding_key = p_melding_key;
s :=
REPLACE (
REPLACE (
REPLACE (REPLACE (REPLACE (s,
'##DISC##', vardisc),
'##STDMLD##', varstdmld),
'##KEY##', varsrtdisc || TO_CHAR (p_melding_key)),
'##EXTNR##', varextnr),
'##SUBJECT##', varonderwerp);
IF varspoed <= 2
THEN
s :=
REPLACE (s,
'##SPOED##',
'(' || lcl.l ('lcl_mld_spoed') || ')');
ELSE
s := REPLACE (s, '##SPOED##', '');
END IF;
IF varonroerendgoedkeys IS NOT NULL
THEN
-- Pas op: p.alg_onroerendgoed_keys is niet uniek, daarom alg_v_allonroerendgoed nodig.
SELECT NVL (p.alg_plaatsaanduiding, '')
INTO varplaats
FROM alg_v_plaatsaanduiding_all p, alg_v_allonroerendgoed ao
WHERE p.alg_onroerendgoed_keys = ao.alg_onroerendgoed_keys
AND p.alg_onroerendgoed_type = ao.alg_type
AND ao.alg_onroerendgoed_keys = varonroerendgoedkeys;
s := REPLACE (s, '##PLAATS##', varplaats);
ELSE
s := REPLACE (s, '##PLAATS##', '');
END IF;
END IF;
RETURN s;
END;
FUNCTION opdrsprintf (ps IN varchar2, p_opdr_key IN number)
RETURN varchar2
IS
s VARCHAR2 (2048 CHAR);
f VARCHAR2 (2048 CHAR);
d NUMBER := 0;
fmt VARCHAR2 (50 CHAR);
lmld_melding_key mld_opdr.mld_melding_key%TYPE;
lbedrijfopdr_volgnr mld_opdr.mld_opdr_bedrijfopdr_volgnr%TYPE;
lopdr_omschrijving mld_opdr.mld_opdr_omschrijving%TYPE;
lopdrstatus mld_opdr.mld_statusopdr_key%TYPE;
lafmelderkey fac_tracking.prs_perslid_key%TYPE;
lafmelder prs_v_perslid_fullnames_all.prs_perslid_naam_full%TYPE;
varstdmld mld_stdmelding.mld_stdmelding_omschrijving%TYPE;
vardisc ins_tab_discipline.ins_discipline_omschrijving%TYPE;
varsrtdisc ins_srtdiscipline.ins_srtdiscipline_prefix%TYPE;
varspoed mld_melding.mld_melding_spoed%TYPE;
varonroerendgoedkeys mld_melding.mld_alg_onroerendgoed_keys%TYPE;
varalglocatiekey mld_melding.mld_alg_locatie_key%TYPE;
varplaats VARCHAR2(4000); -- Ook groot genoeg voor locatieomschrijving
varopdrtype mld_typeopdr.mld_typeopdr_omschrijving%TYPE;
varextnr mld_opdr.mld_opdr_externnr%TYPE;
varopdrid mld_opdr.mld_opdr_id%TYPE;
varonderwerp mld_melding.mld_melding_onderwerp%TYPE;
BEGIN
s := ps;
-- We support substitution of placeholders in the messages
-- ##OPDRKEYN## = voorloop+key+/+volgnr: kan $$x bevatten; x is hierin het aantal posities voor voorloop+key
-- ##OPDRKEY## = ins_srtdiscipline_prefix+key+/+volgnr (zie: RWSN#18845!)
-- ##DISC## = ins_discipline_omschrijving
-- ##STDMLD## = mld_stdmelding_omschrijving
-- ##DESC## = mld_opdr_omschrijving (tbv SMS)
-- ##SPOED## = 'SPOED' indien spoed, anders ''
-- ##PLAATS## = plaatsaanduidig van plaats service
-- ##OPDRTYPE## = opdrachttype
-- ##EXTNR## = extern nummer
-- ##OPDRID## = mld_opdr_id
-- ##SUBJECT## = mld_melding_onderwerp
IF (instr2 (s, '#') > 0 AND instr2 (s, '$') > 0)
THEN
f := SUBSTR( s, INSTR2( s, '$$')+2);
f := SUBSTR( f, 1, INSTR2( f, '##')-1);
s := REPLACE( s, '$$'||f, '');
IF f is not null
THEN
BEGIN
d := TO_NUMBER(f);
EXCEPTION
WHEN OTHERS THEN d := 0;
END;
fmt := LPAD('0', d, '0');
END IF;
END IF;
IF instr2 (s, '#') > 0
THEN
SELECT o.mld_melding_key,
o.mld_opdr_bedrijfopdr_volgnr,
o.mld_opdr_omschrijving,
o.mld_statusopdr_key,
o.mld_opdr_externnr,
o.mld_opdr_id,
lcl.x ('mld_typeopdr_omschrijving',
o.mld_typeopdr_key,
ot.mld_typeopdr_omschrijving)
INTO lmld_melding_key,
lbedrijfopdr_volgnr,
lopdr_omschrijving,
lopdrstatus,
varextnr,
varopdrid,
varopdrtype
FROM mld_opdr o, mld_typeopdr ot
WHERE o.mld_typeopdr_key = ot.mld_typeopdr_key AND o.mld_opdr_key = p_opdr_key;
-- Tijdens het tracken van het afmelden is de transactie nog niet
-- afgelopen, en levert het zoeken naar de afmelder via tracking
-- (nog) geen resultaat op. WE KUNNEN HIER DUS NIET NOTIFICEREN
-- WIE ER HEEFT AFGEMELD.
SELECT lcl.x ('mld_stdmelding_omschrijving',
stdm.mld_stdmelding_key,
stdm.mld_stdmelding_omschrijving),
lcl.x ('ins_discipline_omschrijving',
d.ins_discipline_key,
d.ins_discipline_omschrijving),
sd.ins_srtdiscipline_prefix,
m.mld_melding_spoed,
m.mld_alg_onroerendgoed_keys,
m.mld_alg_locatie_key,
m.mld_melding_onderwerp
INTO varstdmld,
vardisc,
varsrtdisc,
varspoed,
varonroerendgoedkeys,
varalglocatiekey,
varonderwerp
FROM mld_melding m,
mld_stdmelding stdm,
ins_tab_discipline d,
ins_srtdiscipline sd
WHERE d.ins_srtdiscipline_key = sd.ins_srtdiscipline_key
AND stdm.mld_ins_discipline_key = d.ins_discipline_key
AND stdm.mld_stdmelding_key = m.mld_stdmelding_key
AND m.mld_melding_key = lmld_melding_key;
IF varonroerendgoedkeys IS NOT NULL
THEN
-- Pas op: p.alg_onroerendgoed_keys is niet uniek, daarom alg_v_allonroerendgoed nodig.
SELECT NVL (p.alg_plaatsaanduiding, '')
INTO varplaats
FROM alg_v_plaatsaanduiding_all p, alg_v_allonroerendgoed ao
WHERE p.alg_onroerendgoed_keys = ao.alg_onroerendgoed_keys
AND p.alg_onroerendgoed_type = ao.alg_type
AND ao.alg_onroerendgoed_keys = varonroerendgoedkeys;
ELSIF varalglocatiekey IS NOT NULL
THEN
SELECT NVL(l.alg_locatie_omschrijving, '')
INTO varplaats
FROM alg_locatie l
WHERE l.alg_locatie_key = varalglocatiekey;
ELSE
varplaats := '';
END IF;
s := REPLACE (REPLACE (REPLACE (REPLACE (REPLACE (REPLACE (REPLACE (REPLACE (REPLACE (REPLACE (s,
'##OPDRKEYN##', CASE WHEN fmt IS NOT NULL THEN LTRIM(TO_CHAR (lmld_melding_key, fmt)) ELSE TO_CHAR (lmld_melding_key) END || '/' || TO_CHAR (lbedrijfopdr_volgnr)),
'##OPDRKEY##', varsrtdisc || TO_CHAR (lmld_melding_key) || '/' || TO_CHAR (lbedrijfopdr_volgnr)),
'##DISC##', vardisc),
'##STDMLD##', varstdmld),
'##DESC##', lopdr_omschrijving),
'##OPDRTYPE##', varopdrtype),
'##EXTNR##', varextnr),
'##OPDRID##', varopdrid),
'##SUBJECT##', varonderwerp),
'##PLAATS##', varplaats);
IF varspoed <= 2
THEN
s := REPLACE (s, '##SPOED##', '(' || lcl.l('lcl_mld_spoed') || ')');
ELSE
s := REPLACE (s, '##SPOED##', '');
END IF;
END IF;
s := REPLACE (s, ' ()', '');
RETURN s;
END;
PROCEDURE upsertmeldingkenmerk (p_kenmerk_key IN NUMBER, p_mld_key IN NUMBER, p_waarde IN VARCHAR2)
IS
v_count NUMBER;
v_waarde mld_kenmerkmelding.mld_kenmerkmelding_waarde%TYPE;
BEGIN
SELECT COUNT ( * ), MIN (mld_kenmerkmelding_waarde)
INTO v_count, v_waarde
FROM mld_kenmerkmelding
WHERE mld_melding_key = p_mld_key
AND mld_kenmerk_key = p_kenmerk_key
AND mld_kenmerkmelding_verwijder IS NULL;
IF v_count = 1
THEN
IF p_waarde IS NULL
THEN
DELETE mld_kenmerkmelding
WHERE mld_melding_key = p_mld_key
AND mld_kenmerk_key = p_kenmerk_key
AND mld_kenmerkmelding_verwijder IS NULL;
ELSE
IF (v_waarde <> p_waarde) THEN
UPDATE mld_kenmerkmelding
SET mld_kenmerkmelding_waarde = p_waarde
WHERE mld_melding_key = p_mld_key
AND mld_kenmerk_key = p_kenmerk_key
AND mld_kenmerkmelding_verwijder IS NULL;
END IF;
END IF;
ELSE
IF p_kenmerk_key IS NOT NULL AND p_waarde IS NOT NULL
THEN
INSERT INTO mld_kenmerkmelding (mld_kenmerk_key,
mld_melding_key,
mld_kenmerkmelding_waarde)
VALUES (p_kenmerk_key, p_mld_key, p_waarde);
END IF;
END IF;
END;
-- Er wordt niet getrackt (wat eigenlijk niet zo goed is)
PROCEDURE upsertopdrachtkenmerk (p_kenmerk_key IN NUMBER, p_opdr_key IN NUMBER, p_waarde IN VARCHAR2)
IS
v_count NUMBER;
v_waarde mld_kenmerkopdr.mld_kenmerkopdr_waarde%TYPE;
BEGIN
SELECT COUNT ( * ), MIN(mld_kenmerkopdr_waarde)
INTO v_count, v_waarde
FROM mld_kenmerkopdr
WHERE mld_opdr_key = p_opdr_key
AND mld_kenmerk_key = p_kenmerk_key
AND mld_kenmerkopdr_verwijder IS NULL;
IF v_count = 1
THEN
IF p_waarde IS NULL
THEN
DELETE mld_kenmerkopdr
WHERE mld_opdr_key = p_opdr_key
AND mld_kenmerk_key = p_kenmerk_key
AND mld_kenmerkopdr_verwijder IS NULL;
ELSE
IF (v_waarde <> p_waarde) THEN
UPDATE mld_kenmerkopdr
SET mld_kenmerkopdr_waarde = p_waarde
WHERE mld_opdr_key = p_opdr_key
AND mld_kenmerk_key = p_kenmerk_key
AND mld_kenmerkopdr_verwijder IS NULL;
END IF;
END IF;
ELSE
IF p_kenmerk_key IS NOT NULL AND p_waarde IS NOT NULL
THEN
INSERT INTO mld_kenmerkopdr (mld_kenmerk_key,
mld_opdr_key,
mld_kenmerkopdr_waarde)
VALUES (p_kenmerk_key, p_opdr_key, p_waarde);
END IF;
END IF;
END;
FUNCTION mldflexsummary (pmelding_key IN NUMBER)
RETURN VARCHAR2
IS
CURSOR c1
IS
SELECT k.mld_kenmerk_key,
t.mld_srtkenmerk_kenmerktype,
t.mld_srtkenmerk_nmin nmin,
t.mld_srtkenmerk_nmax nmax,
t.fac_kenmerkdomein_key,
k.mld_kenmerk_volgnummer,
COALESCE (
lcl.x ('mld_kenmerk_omschrijving', k.mld_kenmerk_key, k.mld_kenmerk_omschrijving),
lcl.x ('mld_srtkenmerk_omschrijving',
t.mld_srtkenmerk_key,
t.mld_srtkenmerk_omschrijving))
mld_kenmerk_omschrijving,
v.mld_kenmerkmelding_waarde
FROM mld_srtkenmerk t, mld_kenmerk k, mld_kenmerkmelding v
WHERE v.mld_kenmerk_key = k.mld_kenmerk_key
AND k.mld_srtkenmerk_key = t.mld_srtkenmerk_key
AND BITAND(t.mld_srtkenmerk_systeem,4) = 0 -- gewoon niet als vertrouwelijk
AND k.mld_kenmerk_verwijder IS NULL
AND t.mld_srtkenmerk_verwijder IS NULL
AND NOT( ( fac.getSetting('mld_ord_flexsummary') = 2
AND BITAND(k.mld_kenmerk_wissen, 4) = 4
)
OR fac.getSetting('mld_ord_flexsummary') = 0
)
AND v.mld_melding_key = pmelding_key
ORDER BY k.mld_kenmerk_volgnummer,
UPPER(COALESCE(mld_kenmerk_omschrijving, mld_srtkenmerk_omschrijving)); --field-order always in native language order
waarde mld_kenmerkmelding.mld_kenmerkmelding_waarde%TYPE;
builder VARCHAR2 (4000 CHAR);
BEGIN
FOR r IN c1 LOOP
waarde := r.mld_kenmerkmelding_waarde;
IF waarde IS NOT NULL AND waarde <> '-1'
-- gevuld
THEN
IF r.mld_srtkenmerk_kenmerktype = 'V'
-- checkbox
THEN
IF waarde = '0'
THEN
waarde := lcl.l ('lcl_check_0');
ELSIF waarde = '1'
THEN
waarde := lcl.l ('lcl_check_1');
END IF;
ELSIF r.mld_srtkenmerk_kenmerktype = 'R' OR r.mld_srtkenmerk_kenmerktype = 'S'
-- referentie
THEN
waarde := flx.getdomeinwaarde (r.fac_kenmerkdomein_key, waarde);
END IF;
-- In het zeldzame geval dat de tekst te lang zou worden slaan we sommige
-- kenmerken gewoon silent over. Niet ideaal maar toch vrij theoretisch
IF (COALESCE(LENGTH(builder),0) + LENGTH(r.mld_kenmerk_omschrijving) + LENGTH(waarde) < 3990)
THEN
builder := builder || CHR(10) || r.mld_kenmerk_omschrijving || ': ' || waarde;
END IF;
END IF;
END LOOP;
RETURN builder;
END;
PROCEDURE remove(p_melding_key IN NUMBER)
IS
CURSOR c_melding(p_melding_key IN NUMBER) IS
SELECT mld_melding_key
FROM mld_melding
WHERE (mld_melding_start_key <> mld_melding_key AND mld_melding_start_key = p_melding_key)
OR mld_melding_parentkey = p_melding_key;
CURSOR c_opdracht(p_melding_key IN NUMBER) IS
SELECT mld_opdr_key
FROM mld_opdr
WHERE mld_melding_key = p_melding_key;
CURSOR c_bijlagen(p_refkey IN NUMBER) IS
SELECT fac_bijlagen_key
FROM fac_bijlagen b
, mld_melding r
, (SELECT k.mld_kenmerk_key kenmerk_key
FROM mld_kenmerk k
, mld_srtkenmerk s
WHERE k.mld_srtkenmerk_key = s.mld_srtkenmerk_key
AND k.mld_kenmerk_niveau NOT IN ('O', 'P')
AND s.mld_srtkenmerk_kenmerktype IN ('F', 'M', 'E', 'X')
) k
WHERE b.fac_bijlagen_kenmerk_key = k.kenmerk_key
AND b.fac_bijlagen_refkey = r.mld_melding_key
AND b.fac_bijlagen_module = 'MLD'
AND b.fac_bijlagen_refkey = p_refkey;
BEGIN
-- Ook alle child meldingen verwijderen.
FOR ref_melding IN c_melding(p_melding_key)
LOOP
mld.remove(ref_melding.mld_melding_key);
END LOOP;
-- Alle opdrachten onder de melding verwijderen.
FOR ref_opdracht IN c_opdracht(p_melding_key)
LOOP
mld.remove_opdr(ref_opdracht.mld_opdr_key);
END LOOP;
FOR ref_bijlagen IN c_bijlagen(p_melding_key)
LOOP
flx.deleteflexbijlage (ref_bijlagen.fac_bijlagen_key);
END LOOP;
DELETE FROM mld_melding
WHERE mld_melding_key = p_melding_key;
-- Van de volgende tabellen worden de records die naar deze p_melding_key
-- verwijzen met ON DELETE CASCADE ook verwijderd:
-- mld_melding_note
-- mld_kenmerkmelding
-- mld_melding_object
-- prj_scenario
-- In de volgende tabel wordt mld_melding_key leeg gemaakt bij het verwijderen van p_melding_key:
-- bes_bestelling
fac.remove_tracking('melding', p_melding_key);
END;
PROCEDURE remove_opdr(p_mld_opdr_key IN NUMBER)
IS
CURSOR c_factuur(p_opdracht_key IN NUMBER) IS
SELECT fin_factuur_key
FROM fin_factuur
WHERE mld_opdr_key = p_opdracht_key;
CURSOR c_afspraak(p_opdracht_key IN NUMBER) IS
SELECT bez_afspraak_key
FROM bez_afspraak
WHERE mld_opdr_key = p_opdracht_key;
CURSOR c_bijlagen(p_refkey IN NUMBER) IS
SELECT fac_bijlagen_key
FROM fac_bijlagen b
, mld_opdr r
, (SELECT k.mld_kenmerk_key kenmerk_key
FROM mld_kenmerk k
, mld_srtkenmerk s
WHERE k.mld_srtkenmerk_key = s.mld_srtkenmerk_key
AND k.mld_kenmerk_niveau IN ('O', 'P')
AND s.mld_srtkenmerk_kenmerktype IN ('F', 'M', 'E', 'X')
) k
WHERE b.fac_bijlagen_refkey = r.mld_opdr_key
AND b.fac_bijlagen_module = 'MLD'
AND b.fac_bijlagen_refkey = p_refkey;
BEGIN
FOR ref_factuur IN c_factuur(p_mld_opdr_key)
LOOP
fin.remove(ref_factuur.fin_factuur_key);
END LOOP;
FOR ref_afspraak IN c_afspraak(p_mld_opdr_key)
LOOP
bez.remove(ref_afspraak.bez_afspraak_key);
END LOOP;
FOR ref_bijlagen IN c_bijlagen(p_mld_opdr_key)
LOOP
flx.deleteflexbijlage (ref_bijlagen.fac_bijlagen_key);
END LOOP;
DELETE FROM mld_opdr
WHERE mld_opdr_key = p_mld_opdr_key;
-- Van de volgende tabellen worden de records die naar deze mld_opdr_key
-- verwijzen met ON DELETE CASCADE ook verwijderd:
-- mld_opdr_note
-- mld_kenmerkopdr
-- mld_opdr_materiaal
-- mld_opdr_uitvoeren
-- mld_opdr_uren
-- Hierdoor worden de afhankelijkheden in de volgende tabel ook verwijderd:
-- mld_opdruren_kosten
fac.remove_tracking('opdracht', p_mld_opdr_key);
END;
END mld;
/
REGISTERRUN('$Id$')
#endif // MLD