1924 lines
87 KiB
MySQL
1924 lines
87 KiB
MySQL
--
|
|
-- $Id$
|
|
--
|
|
-- Script containing customer specific sql statements for the FACILITOR database
|
|
-- Voor dbuser invullen: - indien script voor 1 klant is: 'MARX' (de klantcode, zoals vermeld in fac_version_cust)
|
|
-- - script is voor meerdere klanten: 'AAXX' (de groepcode, zoals vermeld in fac_version_group)
|
|
-- - script is voor meerdere klanten met naam volgens een bepaald patroon: '^AA|^ASMS|^GULU|^NMMS|^RABO|^ZKHM'
|
|
-- Ook als het script gedraaid wordt voor de verkeerde cust wordt er een logfile gemaakt.
|
|
-- (dit in tegenstelling tot sample_xxxx.sql)
|
|
|
|
DEFINE thisfile = 'MAREON_PLAN.SQL'
|
|
DEFINE dbuser = '^MARX'
|
|
|
|
SET ECHO ON
|
|
SET DEFINE ON
|
|
COLUMN fcltlogfile NEW_VALUE fcltlogfile NOPRINT;
|
|
COLUMN fcltcusttxt NEW_VALUE fcltcusttxt NOPRINT;
|
|
WHENEVER SQLERROR CONTINUE;
|
|
SELECT adm.getscriptspoolfile('&thisfile') AS fcltlogfile FROM DUAL;
|
|
SPOOL &fcltlogfile
|
|
WHENEVER SQLERROR EXIT;
|
|
SELECT adm.checkscriptcust('&dbuser') AS fcltcusttxt FROM DUAL;
|
|
WHENEVER SQLERROR CONTINUE;
|
|
---------------------------------------
|
|
PROMPT &fcltcusttxt
|
|
---------------------------------------
|
|
SET DEFINE OFF
|
|
|
|
------ payload begin ------
|
|
|
|
|
|
--------------------- MAREON PLANNING --------------------- MAREON PLANNING --------------------- MAREON PLANNING --------------------- MAREON PLANNING --------------------- MAREON PLANNING ------------------
|
|
|
|
-- MARX#66773 Module Mareon Planning
|
|
-- Check of leverancier de module Mareon Planning heeft afgenomen, dus of deze geautoriseerd is voor planningen, oftewel: staat prs_kenmerk_key 61 AAN (of UIT).
|
|
-- Waarde 0: nee, niet geautoriseerd voor module Planbord
|
|
-- Waarde 1: ja, wel geautoriseerd voor module Planbord
|
|
-- Waarde 2: ja, wel geautoriseerd voor module Planbord EN geautoriseerd voor Mareon Premium Groene Planning
|
|
|
|
CREATE OR REPLACE FUNCTION marx_bedrijf_auth_4_plan (v_prs_bedrijf_key IN NUMBER)
|
|
RETURN NUMBER
|
|
AS
|
|
v_geautoriseerd NUMBER(10);
|
|
BEGIN
|
|
SELECT COALESCE (MAX (prs_kenmerklink_waarde), '0')
|
|
INTO v_geautoriseerd
|
|
FROM prs_kenmerklink
|
|
WHERE prs_kenmerk_key = 61 AND prs_kenmerklink_niveau = 'B' AND prs_link_key = v_prs_bedrijf_key;
|
|
|
|
RETURN v_geautoriseerd;
|
|
END;
|
|
/
|
|
|
|
CREATE OR REPLACE FUNCTION marx_bedrijf_auth_4_planbord (v_prs_bedrijf_key IN NUMBER)
|
|
RETURN NUMBER
|
|
AS
|
|
BEGIN
|
|
IF marx_bedrijf_auth_4_plan(v_prs_bedrijf_key) = 1 OR marx_bedrijf_auth_4_plan(v_prs_bedrijf_key) = 2
|
|
THEN
|
|
RETURN 1;
|
|
ELSE
|
|
RETURN 0;
|
|
END IF;
|
|
END;
|
|
/
|
|
|
|
-- MARX#73599 Planningsberichten: vertaling van vaardigheid(code) van opdrachtgever
|
|
-- Extra check: heeft leverancier wel Planning Premium ingetsteld?
|
|
-- Dit bepalen we ahdv technisch adres, staat deze voor v_prs_bedrijf_key wel ingesteld
|
|
CREATE OR REPLACE FUNCTION marx_bedrijf_auth_4premiumplan (v_prs_bedrijf_key IN NUMBER)
|
|
RETURN NUMBER
|
|
AS
|
|
v_geautoriseerd NUMBER(10);
|
|
BEGIN
|
|
SELECT COALESCE (MAX (prs_kenmerklink_waarde), '0')
|
|
INTO v_geautoriseerd
|
|
FROM prs_kenmerklink
|
|
WHERE prs_kenmerk_key = 61 AND prs_kenmerklink_niveau = 'B' AND prs_link_key = v_prs_bedrijf_key;
|
|
|
|
SELECT DECODE(count(*),0,0,1)
|
|
INTO v_geautoriseerd
|
|
FROM prs_bedrijfadres ba
|
|
WHERE ba.prs_bedrijfadres_type = 'V'
|
|
AND ba.prs_bedrijf_key = v_prs_bedrijf_key
|
|
AND ba.prs_bedrijfadres_startdatum = (SELECT MAX(ba2.prs_bedrijfadres_startdatum)
|
|
FROM prs_bedrijfadres ba2
|
|
WHERE ba2.prs_bedrijf_key = ba.prs_bedrijf_key AND ba2.prs_bedrijfadres_type = 'V' AND ba2.prs_bedrijfadres_startdatum <= SYSDATE);
|
|
RETURN v_geautoriseerd;
|
|
END;
|
|
/
|
|
|
|
|
|
-- MARX#70053 Mareon Premium Groene Planningen: plannen met geografische optimalisatie
|
|
-- Waarde 0: geen autorisatie voor Groene Planning, waarde 1 wel autorisatie.
|
|
CREATE OR REPLACE FUNCTION marx_bedrijf_auth_4_greenplan (v_prs_bedrijf_key IN NUMBER)
|
|
RETURN NUMBER
|
|
AS
|
|
BEGIN
|
|
IF marx_bedrijf_auth_4_plan(v_prs_bedrijf_key) = 2
|
|
THEN
|
|
RETURN 1;
|
|
ELSE
|
|
RETURN 0;
|
|
END IF;
|
|
END;
|
|
/
|
|
|
|
-- MARX#66773 Module Mareon Planning
|
|
-- View met name bedoeld voor de LEV bedrijven, die default geen afdeling hebben (is verder ook niet nodig / interessant),
|
|
-- Alleen wel nodig wanneer LEV gebruik wil maken van het Mareon planbord, dan moeten de perslid's van de contactpersonen ff in een aparte afdeling i.v.m. WEB_RESFOF scope die op/per BEDRIJF is, zodat de andere users onzichtbaar blijven.
|
|
-- Deze view wordt gebuikt bij de initplanning en aanmaak nieuwe personen (beheer contactpersoon).
|
|
CREATE OR REPLACE VIEW marx_v_bedrijf_afdeling
|
|
(
|
|
prs_bedrijf_key,
|
|
prs_bedrijf_naam,
|
|
prs_afdeling_key
|
|
)
|
|
AS SELECT b.prs_bedrijf_key, b.prs_bedrijf_naam, COALESCE(a.prs_afdeling_key, 1)
|
|
FROM prs_afdeling a, prs_bedrijf b
|
|
WHERE b.prs_bedrijf_key = a.prs_bedrijf_key(+);
|
|
|
|
|
|
|
|
-- Aanmaken van nieuwe (aparte) API user voor het (alleen) kunnen opvragen van planvoorstellen en inschieten van plankeuze bij (eigen) leveranciers
|
|
CREATE OR REPLACE PROCEDURE marx_create_woco_planner
|
|
(p_prs_bedrijf_key IN NUMBER)
|
|
AS
|
|
v_prs_bedrijf_naam VARCHAR2(100);
|
|
v_prs_afdeling_key NUMBER(10);
|
|
v_prs_perslid_apikey VARCHAR2(100);
|
|
v_prs_perslid_key NUMBER(10);
|
|
v_prs_srtperslid_key NUMBER(10);
|
|
|
|
BEGIN
|
|
----------- Start procedure ---
|
|
|
|
-- Functie (prs_srtperslid) voor "woco planning" heeft key 20, om te kunnen onderscheiden van "woco onderhoud".
|
|
v_prs_srtperslid_key:= 20;
|
|
|
|
SELECT prs_bedrijf_naam
|
|
INTO v_prs_bedrijf_naam
|
|
FROM prs_bedrijf
|
|
WHERE prs_bedrijf_key = p_prs_bedrijf_key;
|
|
|
|
-- de eerste de beste is oke.
|
|
SELECT MIN(prs_afdeling_key)
|
|
INTO v_prs_afdeling_key
|
|
FROM prs_afdeling
|
|
WHERE prs_bedrijf_key = p_prs_bedrijf_key;
|
|
|
|
v_prs_perslid_apikey := DBMS_RANDOM.STRING ('x', 32);
|
|
|
|
|
|
--- Aanmaken persoon met functie 'Opdrachtgever-API' (srtperlid_key = 222), Achternaam overnemen van bedrijfnaam,
|
|
INSERT INTO prs_perslid (prs_perslid_module,
|
|
prs_srtperslid_key,
|
|
prs_afdeling_key,
|
|
prs_perslid_naam,
|
|
prs_perslid_oslogin,
|
|
prs_perslid_apikey)
|
|
VALUES ('PRS',
|
|
v_prs_srtperslid_key,
|
|
v_prs_afdeling_key,
|
|
SUBSTR ('PLN-' || v_prs_bedrijf_naam , 1, 60),
|
|
SUBSTR ('PLN-' || v_prs_bedrijf_naam , 1, 60),
|
|
v_prs_perslid_apikey)
|
|
RETURNING prs_perslid_key
|
|
INTO v_prs_perslid_key;
|
|
|
|
-- fac_groep_key 16 is gereserveerd voor woco planning
|
|
INSERT INTO fac_gebruikersgroep (fac_groep_key, prs_perslid_key)
|
|
VALUES (16, v_prs_perslid_key);
|
|
|
|
|
|
COMMIT;
|
|
END;
|
|
/
|
|
|
|
|
|
-- MARX#66773 Module Mareon Planning
|
|
-- Bestaat er al een gereserveerde/optie res_rsv_ruimte voor deze woco met dit ionr? (op MARX-nivo, dus dat res_rsv_ruimte.mld_opdr_key leeg is)
|
|
-- Dus nog zonder dat de mld_opdr aan de res_rsv_ruimte is gekoppeld (dus niet op FCLT-nivo, dus dat res_rsv_ruimte.mld_opdr_key gevuld is)
|
|
CREATE OR REPLACE FUNCTION marx_ion_already_planned (v_woco_key IN NUMBER, v_ion_nr IN VARCHAR2)
|
|
RETURN NUMBER
|
|
AS
|
|
v_res_rsv_ruimte_key NUMBER(10);
|
|
BEGIN
|
|
SELECT MIN(rrr.res_rsv_ruimte_key)
|
|
INTO v_res_rsv_ruimte_key
|
|
FROM res_rsv_ruimte rrr
|
|
WHERE rrr.res_rsv_ruimte_key=
|
|
(SELECT MIN(kw2.res_rsv_ruimte_key)
|
|
FROM res_kenmerkwaarde kw1, res_kenmerkwaarde kw2
|
|
WHERE kw1.res_kenmerk_key = 2
|
|
AND kw1.res_kenmerkreservering_waarde = TO_CHAR(v_woco_key)
|
|
AND kw1.res_kenmerkwaarde_verwijder IS NULL
|
|
AND kw1.res_rsv_ruimte_key = kw2.res_rsv_ruimte_key
|
|
AND kw2.res_kenmerk_key = 1
|
|
AND kw2.res_kenmerkreservering_waarde = v_ion_nr
|
|
AND kw2.res_kenmerkwaarde_verwijder IS NULL)
|
|
AND rrr.res_rsv_ruimte_verwijder IS NULL;
|
|
|
|
RETURN v_res_rsv_ruimte_key;
|
|
END;
|
|
/
|
|
|
|
-- MARX#66773 Module Mareon Planning
|
|
-- Is de mld_opdr als officieel gepland via een res_rsv_ruimte, dus op FCLT-nivo, res_rsv_ruimte.mld_opdr_key gevuld is
|
|
CREATE OR REPLACE FUNCTION marx_mld_opdr_already_planned (v_mld_opdr_key IN NUMBER)
|
|
RETURN NUMBER
|
|
AS
|
|
v_res_rsv_ruimte_key NUMBER(10);
|
|
BEGIN
|
|
SELECT MIN(res_rsv_ruimte_key)
|
|
INTO v_res_rsv_ruimte_key
|
|
FROM res_rsv_ruimte
|
|
WHERE mld_opdr_key = v_mld_opdr_key
|
|
AND res_rsv_ruimte_verwijder IS NULL;
|
|
|
|
RETURN v_res_rsv_ruimte_key;
|
|
END;
|
|
/
|
|
|
|
-- MARX#66773 Module Mareon Planning
|
|
-- Is er een mld_opdr die bestaat bij dit IONR van deze WOCO (opdrachtgever)?
|
|
CREATE OR REPLACE FUNCTION marx_get_mld_opdr_via_ionr (v_woco_key IN NUMBER, v_ion_nr IN VARCHAR2)
|
|
RETURN NUMBER
|
|
AS
|
|
v_mld_opdr_key NUMBER(10);
|
|
BEGIN
|
|
SELECT MAX(mld_opdr_key)
|
|
INTO v_mld_opdr_key
|
|
FROM mld_opdr o, mld_melding m, mar_v_woco_perslid woco1
|
|
WHERE mld_opdr_id = v_ion_nr
|
|
AND o.mld_melding_key = m.mld_melding_key
|
|
AND m.prs_perslid_key = woco1.prs_perslid_key
|
|
AND woco1.prs_bedrijf_key = v_woco_key;
|
|
|
|
RETURN v_mld_opdr_key;
|
|
END;
|
|
/
|
|
|
|
|
|
CREATE OR REPLACE PROCEDURE marx_delete_res_bij_mld_opdr (v_mld_opdr_key IN NUMBER)
|
|
AS
|
|
-- Alle toekomstige reserveringen bij opdracht mld_opdr_key
|
|
CURSOR c1
|
|
IS
|
|
SELECT res_rsv_ruimte_key
|
|
FROM res_rsv_ruimte
|
|
WHERE mld_opdr_key = v_mld_opdr_key
|
|
AND res_rsv_ruimte_van > SYSDATE
|
|
AND res_rsv_ruimte_verwijder IS NULL;
|
|
BEGIN
|
|
FOR rec1 IN c1
|
|
LOOP
|
|
BEGIN
|
|
res.remove(rec1.res_rsv_ruimte_key);
|
|
END;
|
|
END LOOP;
|
|
END;
|
|
/
|
|
|
|
-- Initialiseer voor leverancier de PLANning-randvoorwaarden, zoals catalogus, autorisaties etc
|
|
|
|
-- Controle of leverancier al een eigen 'leveranciers'catalogus voor PLANNEN heeft
|
|
CREATE OR REPLACE FUNCTION marx_bedrijf_has_plan_cat(v_bedrijf_key IN NUMBER)
|
|
RETURN NUMBER
|
|
AS
|
|
v_res_ins_discipline_key NUMBER(10);
|
|
BEGIN
|
|
-- Eerst checken of leverancier al een eigen 'leveranciers' RES-PLANNING catalogus heeft
|
|
SELECT MAX(res_ins_discipline_key)
|
|
INTO v_res_ins_discipline_key
|
|
FROM res_disc_params
|
|
WHERE prs_bedrijf_key = v_bedrijf_key;
|
|
|
|
RETURN v_res_ins_discipline_key;
|
|
END;
|
|
/
|
|
|
|
-- v_role_id = PLANNER of PLANBAAR
|
|
CREATE OR REPLACE FUNCTION marx_construct_groep_externid(v_bedrijf_key IN NUMBER, v_role_id IN VARCHAR2)
|
|
RETURN VARCHAR2
|
|
AS
|
|
BEGIN
|
|
RETURN SUBSTR(v_bedrijf_key || '-' || v_role_id, 1, 128);
|
|
END;
|
|
/
|
|
|
|
-- Vanwege ontbreken van prs_bedrijf_key in fac_groep gaan we voor bedrijf X in kolom fac_groep_externid een consequente naamgeving geven, omdat deze nodig is om (op een later moment) een persoon van bedrijf X aan te kunnen koppelen
|
|
-- v_role = PLANNER of PLANBAAR
|
|
CREATE OR REPLACE FUNCTION marx_bedrijf_facgroep(v_bedrijf_key IN NUMBER, v_role IN VARCHAR2)
|
|
RETURN NUMBER
|
|
AS
|
|
v_fac_groep_key NUMBER(10);
|
|
v_fac_groep_externid VARCHAR2(128);
|
|
|
|
BEGIN
|
|
v_fac_groep_externid := marx_construct_groep_externid(v_bedrijf_key, v_role);
|
|
-- Eerst checken of leverancier al een eigen 'leveranciers'catalogus heeft
|
|
SELECT MAX(fac_groep_key)
|
|
INTO v_fac_groep_key
|
|
FROM fac_groep
|
|
WHERE fac_groep_externid = v_fac_groep_externid;
|
|
RETURN v_fac_groep_key;
|
|
END;
|
|
/
|
|
|
|
-- Controle of persoon toekomstige reserveringen heeft, dwz al is ingepland (d.w.z. res_rsv_deel records bestaan bij deze persoon).
|
|
-- Reserveringen uit het (verre) verleden doen niet mee, en uit het recente verleden (afgelopen 2 weken) worden voor het gemak direct ff afgemeld (is ws de bedoeling).
|
|
CREATE OR REPLACE FUNCTION marx_perslid_is_gepland(v_perslid_key IN NUMBER)
|
|
RETURN NUMBER
|
|
AS
|
|
v_aantal NUMBER(10);
|
|
BEGIN
|
|
-- Een res_deel mag niet inactief worden als er nog *openstaande* reserveringen zijn, zie TRIGGER(res_t_res_deel_B_IU) in bestand RES_TRI.SRC
|
|
-- Daarom sluiten we gewoon alle reserveringen met dit res_deel vanaf 14 dagen geleden tot en met nu, dus status op 5 (=afgemeld) zetten
|
|
UPDATE res_rsv_deel rd
|
|
SET rd.res_status_bo_key = 5
|
|
WHERE rd.res_rsv_deel_verwijder IS NULL
|
|
AND EXISTS (SELECT 'x' FROM res_deel d
|
|
WHERE rd.res_deel_key = d.res_deel_key
|
|
AND d.res_prs_perslid_key = v_perslid_key
|
|
AND d.res_deel_verwijder IS NULL
|
|
AND rd.res_rsv_deel_tot > SYSDATE - 14
|
|
AND rd.res_rsv_deel_tot < SYSDATE
|
|
AND rd.res_status_bo_key = 2);
|
|
|
|
SELECT count(*)
|
|
INTO v_aantal
|
|
FROM res_deel d, res_rsv_deel rd
|
|
WHERE d.res_prs_perslid_key = v_perslid_key
|
|
AND d.res_deel_verwijder IS NULL
|
|
AND rd.res_deel_key = d.res_deel_key
|
|
AND rd.res_rsv_deel_tot >= SYSDATE
|
|
AND rd.res_status_bo_key = 2
|
|
AND rd.res_rsv_deel_verwijder IS NULL;
|
|
|
|
RETURN v_aantal;
|
|
END;
|
|
/
|
|
|
|
-- Maak voor leverancier met v_bedrijf_key de initiele zaken aan, zoals:
|
|
-- 1. RES-Catalogus (voor alleen dit bedrijf), en koppelen aan activiteit
|
|
-- 2. Autorisatiegroep incl rechten voor PLANNER aanmaken (RESFOF op BEDRIJF nivo), en taggen met unieke 'externe' id
|
|
-- 3. Autorisatiegroep voor PLANBAAR aanmaken, en taggen met unieke 'externe' id
|
|
CREATE OR REPLACE PROCEDURE marx_init_planning
|
|
(v_bedrijf_key IN NUMBER)
|
|
AS
|
|
l_disc_key NUMBER(10);
|
|
v_prs_bedrijf_naam VARCHAR2(100);
|
|
v_prefix VARCHAR2(10);
|
|
v_ins_discipline_key NUMBER(10);
|
|
l_ins_discipline_omschrijving VARCHAR(100);
|
|
v_fac_groep_key NUMBER(10);
|
|
l_fac_groep_omschrijving VARCHAR(100);
|
|
v_fac_groep_externid VARCHAR2(128);
|
|
v_facgroep_key NUMBER(10);
|
|
v_prs_afdeling_key NUMBER(10);
|
|
BEGIN
|
|
-- We starten eerst met maken van een eigen afdeling voor LEV, dit ivm RESFOF rechten op BEDRIJF nivo
|
|
SELECT prs_afdeling_key, prs_bedrijf_naam
|
|
INTO v_prs_afdeling_key, v_prs_bedrijf_naam
|
|
FROM marx_v_bedrijf_afdeling
|
|
WHERE prs_bedrijf_key = v_bedrijf_key;
|
|
|
|
IF v_prs_afdeling_key = 1
|
|
THEN
|
|
-- Dit betekent dat LEV nog ZELF geen afdeling heeft, maar dat alle personen op de algemene afdeling 'Leverancier' (key 1) 'zitten' (default)
|
|
-- Dus aanmaken nieuwe afdeling voor LEV...
|
|
v_prefix := 'LEV - ';
|
|
INSERT INTO prs_afdeling (prs_bedrijf_key, prs_afdeling_naam, prs_afdeling_omschrijving)
|
|
VALUES (v_bedrijf_key, 'X', SUBSTR(v_prefix || v_prs_bedrijf_naam,1,60))
|
|
RETURNING prs_afdeling_key
|
|
INTO v_prs_afdeling_key;
|
|
|
|
--Eenmalige 'mini'-conversie van de personen van LEV naar de nieuwe afdeling.
|
|
UPDATE prs_perslid
|
|
SET prs_afdeling_key = v_prs_afdeling_key
|
|
WHERE prs_perslid_key IN (SELECT prs_perslid_key FROM prs_contactpersoon
|
|
WHERE prs_bedrijf_key = v_bedrijf_key
|
|
AND prs_perslid_key IS NOT NULL
|
|
AND prs_contactpersoon_verwijder IS NULL);
|
|
END IF;
|
|
|
|
-- Vervolgens checken of leverancier al een eigen 'leveranciers'catalogus heeft
|
|
l_disc_key := marx_bedrijf_has_plan_cat(v_bedrijf_key);
|
|
IF l_disc_key IS NULL
|
|
THEN
|
|
-- Nog geen catalogus, dus aanmaken...
|
|
-- Unieke naam voor catalogus: bedrijfs_naam + bedrijfs_key
|
|
|
|
v_prefix := 'PLAN';
|
|
l_ins_discipline_omschrijving := SUBSTR(v_prefix || ' - ' || v_prs_bedrijf_naam || ' (' || v_bedrijf_key || ')', 1, 60);
|
|
|
|
-- ins_discipline_min_level = 4 betekent "Persoon resource"
|
|
INSERT INTO ins_tab_discipline (ins_discipline_module, ins_discipline_omschrijving, ins_discipline_min_level, ins_discipline_kpnverplicht, ins_discipline_btw)
|
|
VALUES ('RES', l_ins_discipline_omschrijving, 4, 0, 1) RETURNING ins_discipline_key INTO v_ins_discipline_key;
|
|
INSERT INTO res_disc_params (prs_bedrijf_key, res_ins_discipline_key, res_disc_params_expire_dagen, res_disc_params_cancel_dagen, res_disc_params_maxduur)
|
|
VALUES (v_bedrijf_key, v_ins_discipline_key, 0, 0, 10);
|
|
-- Koppelen aan activiteit "Plannen medewerker" (key 11)
|
|
INSERT INTO res_activiteitdiscipline(res_discipline_key, res_activiteit_key)
|
|
VALUES (v_ins_discipline_key, 11);
|
|
END IF;
|
|
v_prefix := 'PLANNER';
|
|
v_facgroep_key := marx_bedrijf_facgroep(v_bedrijf_key, v_prefix);
|
|
IF v_facgroep_key IS NULL
|
|
THEN
|
|
-- Nog geen vakgroep voor de 'PLANNER', aanmaken dus...
|
|
|
|
-- Autorisatiegroep Planner (voor deze leverancier), met een unieke omschrijving "PLANNER-key-bedrijfsnaam" (max 30 tekens)
|
|
l_fac_groep_omschrijving := SUBSTR(v_prefix || '-' || v_bedrijf_key || '-' || v_prs_bedrijf_naam, 1, 30);
|
|
v_fac_groep_externid := marx_construct_groep_externid(v_bedrijf_key, v_prefix);
|
|
INSERT INTO fac_groep (fac_groep_omschrijving, fac_groep_externid)
|
|
VALUES (l_fac_groep_omschrijving, v_fac_groep_externid) RETURNING fac_groep_key INTO v_fac_groep_key;
|
|
-- RESFOF, ALG onbeperkt (nvt) en PRS op BEDRIJF-NIVO (alleen personen binnen het LEV bedrijf)...
|
|
INSERT INTO fac_groeprechten (fac_groep_key, fac_functie_key, ins_discipline_key, fac_gebruiker_alg_level_read, fac_gebruiker_alg_level_write, fac_gebruiker_prs_level_read, fac_gebruiker_prs_level_write)
|
|
SELECT v_fac_groep_key, fac_functie_key, v_ins_discipline_key, -1, -1, 0, 0
|
|
FROM fac_functie
|
|
WHERE fac_functie_code = 'WEB_RESFOF';
|
|
END IF;
|
|
v_prefix := 'PLANBAAR';
|
|
v_facgroep_key := marx_bedrijf_facgroep(v_bedrijf_key, v_prefix);
|
|
IF v_facgroep_key IS NULL
|
|
THEN
|
|
-- Nog geen vakgroep voor de 'PLANBAAR' medewerker, aanmaken dus...
|
|
-- Autorisatiegroep Planbare medewerker (voor deze leverancier), met een unieke omschrijving "PLANBAAR-key-bedrijfsnaam" (max 30 tekens)
|
|
l_fac_groep_omschrijving := SUBSTR(v_prefix || '-' || v_bedrijf_key || '-' || v_prs_bedrijf_naam, 1, 30);
|
|
v_fac_groep_externid := marx_construct_groep_externid(v_bedrijf_key, v_prefix);
|
|
INSERT INTO fac_groep (fac_groep_omschrijving, fac_groep_externid)
|
|
VALUES (l_fac_groep_omschrijving, v_fac_groep_externid) RETURNING fac_groep_key INTO v_fac_groep_key;
|
|
|
|
-- TODO Hier ook nog rechten voor groep 15, wellicht resuse?
|
|
END IF;
|
|
-- MARX#82209 "Omgevallen? Toevoegen van medewerkers bij een (RES)planning is niet mogelijk"
|
|
-- Het is nodig dat er 'extra' records prs_bedrijfdienstlocatie zijn waarin de diensten bij (extern) bedrijf geregistreerd moeten zijn (eerder was dit niet nodig).
|
|
-- Dwz veld prs_bedrijf_key (=leverancier) moet nu gevuld worden: dat doen we met een INSERT:
|
|
INSERT INTO prs_bedrijfdienstlocatie (prs_bedrijf_key, prs_dienst_key, mld_autoorder)
|
|
SELECT v_bedrijf_key, prs_dienst_key, 1
|
|
FROM prs_dienst d
|
|
WHERE NOT EXISTS (SELECT 'x' FROM prs_bedrijfdienstlocatie bd WHERE bd.prs_dienst_key = d.prs_dienst_key AND bd.prs_bedrijf_key = v_bedrijf_key);
|
|
|
|
END;
|
|
/
|
|
|
|
CREATE OR REPLACE PROCEDURE marx_make_perslid_planner (v_bedrijf_key IN NUMBER, v_perslid_key IN NUMBER)
|
|
AS
|
|
v_disc_key NUMBER(10);
|
|
v_prefix VARCHAR2(10);
|
|
v_facgroep_key NUMBER(10);
|
|
v_aantal NUMBER(10);
|
|
----------- Start procedure ---
|
|
BEGIN
|
|
|
|
-- GET RES-PLAN leveranciers'catalogus
|
|
v_disc_key := marx_bedrijf_has_plan_cat(v_bedrijf_key);
|
|
IF v_disc_key IS NOT NULL
|
|
THEN
|
|
|
|
-- Op zoek naar de autorisatie-groep voor de 'planner' personen dit bedrijf...
|
|
v_prefix := 'PLANNER';
|
|
v_facgroep_key := marx_bedrijf_facgroep(v_bedrijf_key, v_prefix);
|
|
|
|
SELECT COUNT (*)
|
|
INTO v_aantal
|
|
FROM fac_gebruikersgroep
|
|
WHERE fac_groep_key = v_facgroep_key AND prs_perslid_key = v_perslid_key;
|
|
|
|
IF v_aantal = 0
|
|
THEN
|
|
INSERT INTO fac_gebruikersgroep (fac_groep_key, prs_perslid_key)
|
|
VALUES (v_facgroep_key, v_perslid_key);
|
|
END IF;
|
|
END IF;
|
|
END;
|
|
/
|
|
|
|
CREATE OR REPLACE PROCEDURE marx_undo_perslid_planner (v_bedrijf_key IN NUMBER, v_perslid_key IN NUMBER)
|
|
AS
|
|
|
|
v_facgroep_key NUMBER(10);
|
|
v_prefix VARCHAR2(10);
|
|
v_aantal NUMBER(10);
|
|
----------- Start procedure ---
|
|
BEGIN
|
|
|
|
-- Op zoek naar de autorisatie-groep voor de 'planner' personen dit bedrijf...
|
|
v_prefix := 'PLANNER';
|
|
v_facgroep_key := marx_bedrijf_facgroep(v_bedrijf_key, v_prefix);
|
|
|
|
DELETE FROM fac_gebruikersgroep
|
|
WHERE fac_groep_key = v_facgroep_key
|
|
AND prs_perslid_key = v_perslid_key;
|
|
|
|
END;
|
|
/
|
|
|
|
|
|
-- MARX#66773 Module Mareon Planning
|
|
CREATE OR REPLACE PROCEDURE marx_make_perslid_planbaar (v_bedrijf_key IN NUMBER, v_perslid_key IN NUMBER)
|
|
AS
|
|
v_disc_key NUMBER(10);
|
|
v_facgroep_key NUMBER(10);
|
|
v_res_deel_omschrijving VARCHAR2(60);
|
|
v_prefix VARCHAR2(10);
|
|
v_aantal NUMBER(10);
|
|
----------- Start procedure ---
|
|
BEGIN
|
|
|
|
-- GET RES-PLAN leveranciers'catalogus
|
|
v_disc_key := marx_bedrijf_has_plan_cat(v_bedrijf_key);
|
|
IF v_disc_key IS NOT NULL
|
|
THEN
|
|
-- MARX#70903 Meerdere vaardigheden (expertises) voor 1 resource (persoon) kunnen registreren
|
|
-- Planbaar had voorheen (exact) 1 soort-perslid (competentie), nu niet meer, planbaar betekent dat je planbaar bent, en of dat nu voor 0, 1, 2 , 3 , ... competenties.
|
|
SELECT SUBSTR(prs_perslid_naam_friendly, 1, 60)
|
|
INTO v_res_deel_omschrijving
|
|
FROM prs_v_perslid_fullnames p
|
|
WHERE p.prs_perslid_key = v_perslid_key;
|
|
|
|
|
|
-- Was deze persoon al (eerder) planbaar gemaakt (voor dit bedrijf), b.v. onder andere expertise?
|
|
SELECT COUNT(*)
|
|
INTO v_aantal
|
|
FROM res_deel
|
|
WHERE res_discipline_key = v_disc_key
|
|
AND res_prs_perslid_key = v_perslid_key
|
|
AND res_deel_verwijder IS NULL;
|
|
|
|
IF v_aantal = 0
|
|
THEN
|
|
-- Nee dus, niet al (eerder) planbaar gemaakt, dus een insert ...
|
|
INSERT INTO res_deel (res_discipline_key, res_deel_omschrijving, res_deel_alg_level,res_prs_perslid_key)
|
|
VALUES (v_disc_key, v_res_deel_omschrijving, -1, v_perslid_key);
|
|
ELSE
|
|
-- Ja dus, was al (eerder) planbaar, theoretisch kan hier nu andere naam staan, we doen voor zekerheid update...
|
|
UPDATE res_deel
|
|
SET res_deel_omschrijving = v_res_deel_omschrijving
|
|
WHERE res_discipline_key = v_disc_key
|
|
AND res_prs_perslid_key = v_perslid_key;
|
|
END IF;
|
|
|
|
-- Op zoek naar de autorisatie-groep voor de 'planbare' personen dit bedrijf...
|
|
v_prefix := 'PLANBAAR';
|
|
v_facgroep_key := marx_bedrijf_facgroep(v_bedrijf_key, v_prefix);
|
|
|
|
SELECT COUNT (*)
|
|
INTO v_aantal
|
|
FROM fac_gebruikersgroep
|
|
WHERE fac_groep_key = v_facgroep_key AND prs_perslid_key = v_perslid_key;
|
|
|
|
IF v_aantal = 0
|
|
THEN
|
|
INSERT INTO fac_gebruikersgroep (fac_groep_key, prs_perslid_key)
|
|
VALUES (v_facgroep_key, v_perslid_key);
|
|
END IF;
|
|
END IF;
|
|
END;
|
|
/
|
|
|
|
CREATE OR REPLACE PROCEDURE marx_undo_perslid_planbaar (v_bedrijf_key IN NUMBER, v_perslid_key IN NUMBER)
|
|
AS
|
|
|
|
v_facgroep_key NUMBER(10);
|
|
v_prefix VARCHAR2(10);
|
|
v_aantal NUMBER(10);
|
|
----------- Start procedure ---
|
|
BEGIN
|
|
|
|
-- Is deze persoon nog ingepland, dan kan planbaar niet eraf worden gehaald, we geven dan een foutmelding
|
|
v_aantal := marx_perslid_is_gepland(v_perslid_key);
|
|
IF v_aantal = 0
|
|
THEN
|
|
-- Er zijn geen reserveringen meer bij deze persoon, planbaar kan dan weg...
|
|
UPDATE res_deel
|
|
SET res_deel_verwijder = SYSDATE
|
|
WHERE res_prs_perslid_key = v_perslid_key
|
|
AND res_deel_verwijder IS NULL;
|
|
|
|
-- Op zoek naar de autorisatie-groep voor de 'planbare' personen dit bedrijf...
|
|
v_prefix := 'PLANBAAR';
|
|
v_facgroep_key := marx_bedrijf_facgroep(v_bedrijf_key, v_prefix);
|
|
|
|
DELETE FROM fac_gebruikersgroep
|
|
WHERE fac_groep_key = v_facgroep_key
|
|
AND prs_perslid_key = v_perslid_key;
|
|
END IF;
|
|
END;
|
|
/
|
|
|
|
------------------------------------------
|
|
|
|
-- Allerlei praktische/handige functies!!
|
|
|
|
|
|
-- Zoek naar de starttijd van planbare medewerker op bepaalde dag, dit is standaard res_t1, echter indien op deze dag inzetbaarheid bij deze medewerker staat geregistreerd, heeft deze de voorkeur en overrule-t daarmee res_t1
|
|
-- Parameters:
|
|
-- 1. p_res_deel_key is de planbare medewerker
|
|
-- 2. p_datum is de datum waar het om gaat
|
|
CREATE OR REPLACE FUNCTION marx_get_res_t1
|
|
(p_res_deel_key IN NUMBER, p_date IN DATE)
|
|
RETURN DATE
|
|
AS
|
|
l_result_date DATE;
|
|
BEGIN
|
|
|
|
SELECT COALESCE(MAX(TRUNC(p_date) + pi.prs_perslid_inzetbaar_van/(60*24)), TRUNC(p_date) + fac.safe_to_number (fac.getsetting ('res_t1'))/24)
|
|
INTO l_result_date
|
|
FROM res_deel d, prs_perslid_inzetbaar pi
|
|
WHERE d.res_deel_key = p_res_deel_key
|
|
AND d.res_deel_verwijder IS NULL
|
|
AND pi.prs_perslid_key = d.res_prs_perslid_key
|
|
AND pi.prs_perslid_inzetbaar_dag = to_char(p_date,'D') - 1;
|
|
|
|
RETURN l_result_date;
|
|
END;
|
|
/
|
|
|
|
-- Zoek naar de eindtijd van plabare medewerker op bepaalde dag, dit is standaard res_t2, echter indien op deze dag inzetbaarheid bij deze medewerker staat geregistreerd, heeft deze de voorkeur en overrule-t daarmee res_t2
|
|
-- Parameters:
|
|
-- 1. p_res_deel_key is de planbare medewerker
|
|
-- 2. p_datum is de datum waar het om gaat
|
|
CREATE OR REPLACE FUNCTION marx_get_res_t2
|
|
(p_res_deel_key IN NUMBER, p_date IN DATE)
|
|
RETURN DATE
|
|
AS
|
|
l_result_date DATE;
|
|
BEGIN
|
|
|
|
SELECT COALESCE(MAX(TRUNC(p_date) + pi.prs_perslid_inzetbaar_tot/(60*24)), TRUNC(p_date) + fac.safe_to_number (fac.getsetting ('res_t2'))/24)
|
|
INTO l_result_date
|
|
FROM res_deel d, prs_perslid_inzetbaar pi
|
|
WHERE d.res_deel_key = p_res_deel_key
|
|
AND d.res_deel_verwijder IS NULL
|
|
AND pi.prs_perslid_key = d.res_prs_perslid_key
|
|
AND pi.prs_perslid_inzetbaar_dag = to_char(p_date,'D') - 1;
|
|
|
|
RETURN l_result_date;
|
|
END;
|
|
/
|
|
|
|
|
|
-- Zoek naar de dichts bijzijnde reservering voor perslid (res_deel) voorafgaande aan de v_start_datetime1 en die ook een eindtijd heeft na v_start_datetime1 (en die is weer voor v_start_datetime2, anders zit die niet in deze cursor/loop)
|
|
-- Is die er niet, dan beginnen we met zoeken vanaf v_start_datetime1.
|
|
-- Is die er wel, dan beginnen we met zoeken vanaf de eindtijd van de gevonden reservering.
|
|
-- Zijn er hiervan meerdere (wat op zich niet kan) dan zoeken we vanaf de max(eindtijd).
|
|
-- Voor alles geldt dat de starttijd wel na de algemene instelling res_t1 moet liggen. En de starttijd wordt vermeerderd met de p_slack_minutes.
|
|
-- En uiteraard moet de reservering niet de status "vervallen" hebben, die telt niet mee.
|
|
CREATE OR REPLACE FUNCTION marx_get_fromdatetime
|
|
(p_res_deel_key IN NUMBER, p_start_datetime IN DATE, p_start_datetime2 IN DATE, p_slack_minutes IN NUMBER)
|
|
RETURN DATE
|
|
AS
|
|
l_zoeken_vanaf_starttijd DATE;
|
|
l_zoeken_vanaf_res_t1 DATE;
|
|
BEGIN
|
|
BEGIN
|
|
-- De starttijd mag niet eerder dan instelling res_t1 beginnen
|
|
l_zoeken_vanaf_res_t1 := marx_get_res_t1(p_res_deel_key, p_start_datetime);
|
|
|
|
SELECT MAX(rr.res_rsv_ruimte_tot)
|
|
INTO l_zoeken_vanaf_starttijd
|
|
FROM res_rsv_ruimte rr, res_rsv_deel rd
|
|
WHERE rr.res_rsv_ruimte_key = rd.res_rsv_ruimte_key
|
|
AND rr.res_rsv_ruimte_verwijder IS NULL
|
|
AND rd.res_deel_key = p_res_deel_key
|
|
AND rd.res_rsv_deel_verwijder IS NULL
|
|
AND rr.res_rsv_ruimte_van <= GREATEST(p_start_datetime, l_zoeken_vanaf_res_t1)
|
|
AND rr.res_rsv_ruimte_tot > GREATEST(p_start_datetime, l_zoeken_vanaf_res_t1)
|
|
AND rr.res_status_fo_key <> 4;
|
|
|
|
IF l_zoeken_vanaf_starttijd IS NULL
|
|
THEN
|
|
-- Er is geen reservering gevonden die voor p_start_datetime begint en na p_start_datetime eindigt, dus dan is de starttijd gewoon p_start_datetime
|
|
l_zoeken_vanaf_starttijd := p_start_datetime;
|
|
ELSE
|
|
IF l_zoeken_vanaf_starttijd >= p_start_datetime2
|
|
THEN
|
|
-- De starttijd l_zoeken_vanaf_starttijd ligt hier na de eindtijd, dan kunnen we ook stoppen (en niet meer recursief aanroepen)
|
|
l_zoeken_vanaf_starttijd := p_start_datetime2;
|
|
ELSE
|
|
-- Wat op zich niet voor zou mogen komen, maar toch evt kan (= dirty resevering), als er niet netjes na l_zoeken_vanaf_starttijd een nieuwe reservering begint, maar ervoor, we hebben dan van doen met overlappende reservering)
|
|
-- Dan moeten we als starttijd iets naar voren (terug in de tijd), we nemen dan de laatste beginnende reservering met een starttijd na p_start_datetime maar voor l_zoeken_vanaf_starttijd, dus ertussen in.
|
|
-- Daarom roepen we deze functie recursief aan ;-)
|
|
l_zoeken_vanaf_starttijd := marx_get_fromdatetime(p_res_deel_key, l_zoeken_vanaf_starttijd, p_start_datetime2, p_slack_minutes);
|
|
END IF;
|
|
END IF;
|
|
IF l_zoeken_vanaf_starttijd IS NULL OR l_zoeken_vanaf_starttijd <= l_zoeken_vanaf_res_t1
|
|
THEN l_zoeken_vanaf_starttijd := l_zoeken_vanaf_res_t1; -- Bij de starttijd op res_t1 hoeft de p_slack_minutes er niet bij opgesteld te worden
|
|
ELSE l_zoeken_vanaf_starttijd := l_zoeken_vanaf_starttijd + (p_slack_minutes/(60*24));
|
|
END IF;
|
|
EXCEPTION
|
|
WHEN NO_DATA_FOUND
|
|
THEN
|
|
l_zoeken_vanaf_starttijd := NULL;
|
|
WHEN TOO_MANY_ROWS
|
|
THEN
|
|
l_zoeken_vanaf_starttijd := NULL;
|
|
END;
|
|
RETURN l_zoeken_vanaf_starttijd;
|
|
END;
|
|
/
|
|
|
|
-- Op zoek naar de eerst volgende reserverings(begin)tijd res_rsv_ruimte_van, vanaf tijdstip 'p_from_datetime'.
|
|
-- Kan NULL opleveren als er geen reservering meer is.
|
|
-- Voor alles geldt dat de eerst volgende reserveringstijd wel voor de algemene instelling res_t2 moet liggen.
|
|
-- En uiteraard moet de reservering niet de status "vervallen" hebben, die telt niet mee.
|
|
CREATE OR REPLACE FUNCTION marx_get_next_res_starttijd
|
|
(p_res_deel_key IN NUMBER, p_from_datetime IN DATE)
|
|
RETURN DATE
|
|
AS
|
|
l_start_datetime DATE;
|
|
BEGIN
|
|
BEGIN
|
|
SELECT MIN(rr.res_rsv_ruimte_van)
|
|
INTO l_start_datetime
|
|
FROM res_rsv_ruimte rr, res_rsv_deel rd
|
|
WHERE rr.res_rsv_ruimte_key = rd.res_rsv_ruimte_key
|
|
AND rr.res_rsv_ruimte_verwijder IS NULL
|
|
AND rd.res_deel_key = p_res_deel_key
|
|
AND rd.res_rsv_deel_verwijder IS NULL
|
|
AND rr.res_rsv_ruimte_van > p_from_datetime
|
|
AND rr.res_status_fo_key <> 4;
|
|
|
|
EXCEPTION
|
|
WHEN NO_DATA_FOUND
|
|
THEN
|
|
l_start_datetime := NULL;
|
|
WHEN TOO_MANY_ROWS
|
|
THEN
|
|
l_start_datetime := NULL;
|
|
END;
|
|
RETURN l_start_datetime;
|
|
END;
|
|
/
|
|
|
|
-- Op zoek naar de eerst volgende reserverings(eind)tijd res_rsv_ruimte_tot, vanaf tijdstip 'p_from_datetime'.
|
|
-- Deze eindtijd moet wel vermeerderd worden met de p_slack_minutes.
|
|
-- Kan NULL opleveren als er geen reservering meer is.
|
|
-- En uiteraard moet de reservering niet de status "vervallen" hebben, die telt niet mee.
|
|
|
|
CREATE OR REPLACE FUNCTION marx_get_next_res_eindtijd
|
|
(p_res_deel_key IN NUMBER, p_from_datetime IN DATE, p_slack_minutes IN NUMBER)
|
|
RETURN DATE
|
|
AS
|
|
l_eind_datetime DATE;
|
|
BEGIN
|
|
BEGIN
|
|
SELECT MIN(rr.res_rsv_ruimte_tot)
|
|
INTO l_eind_datetime
|
|
FROM res_rsv_ruimte rr, res_rsv_deel rd
|
|
WHERE rr.res_rsv_ruimte_key = rd.res_rsv_ruimte_key
|
|
AND rr.res_rsv_ruimte_verwijder IS NULL
|
|
AND rd.res_deel_key = p_res_deel_key
|
|
AND rd.res_rsv_deel_verwijder IS NULL
|
|
AND rr.res_rsv_ruimte_van >= p_from_datetime
|
|
AND rr.res_status_fo_key <> 4;
|
|
l_eind_datetime := l_eind_datetime + (p_slack_minutes/(60*24));
|
|
EXCEPTION
|
|
WHEN NO_DATA_FOUND
|
|
THEN
|
|
l_eind_datetime := NULL;
|
|
WHEN TOO_MANY_ROWS
|
|
THEN
|
|
l_eind_datetime := NULL;
|
|
END;
|
|
RETURN l_eind_datetime;
|
|
END;
|
|
/
|
|
|
|
|
|
-- Bepaalt het eind moment (datum + tijdstip) van de reservering met een duur van v_duration_minutes, rekening houdende met res_t1 en res_t2.
|
|
CREATE OR REPLACE FUNCTION marx_get_enddatetime
|
|
(v_res_deel_key IN NUMBER,
|
|
v_datetime_start IN DATE,
|
|
v_duration_minutes IN NUMBER)
|
|
RETURN DATE
|
|
AS
|
|
v_date DATE;
|
|
l_vanaf_res_t1 DATE;
|
|
l_tot_res_t2 DATE;
|
|
l_working_minutes NUMBER(10);
|
|
BEGIN
|
|
BEGIN
|
|
l_tot_res_t2 := marx_get_res_t2(v_res_deel_key, v_datetime_start);
|
|
|
|
l_working_minutes := ROUND(24*60*(l_tot_res_t2 - v_datetime_start));
|
|
IF l_working_minutes >= v_duration_minutes
|
|
THEN
|
|
-- Genoeg minuten voor de rest van de dag, we hoeven niet verder naar morgen te kijken, is al oke.
|
|
v_date:= v_datetime_start + (v_duration_minutes/(24*60));
|
|
ELSE
|
|
-- De dag heeft niet genoeg minuten meer, we moeten verder naar morgen kijken...
|
|
-- Oftewel de klus pas niet op deze werkdag, dan recursief aanroepen met morgen vanaf start dag, bij v_duration halen we de gewerkte uren (minuten) van vandaag (tot aan einde vd dag) eraf
|
|
l_vanaf_res_t1 := marx_get_res_t1(v_res_deel_key, v_datetime_start + 1);
|
|
v_date := marx_get_enddatetime(v_res_deel_key, l_vanaf_res_t1, v_duration_minutes - l_working_minutes);
|
|
END IF;
|
|
EXCEPTION
|
|
WHEN NO_DATA_FOUND
|
|
THEN
|
|
v_date := NULL;
|
|
WHEN TOO_MANY_ROWS
|
|
THEN
|
|
v_date := NULL;
|
|
END;
|
|
RETURN v_date;
|
|
END;
|
|
/
|
|
|
|
|
|
-- FUNCTION marx_free_space
|
|
-- Bepaalt of het gat tussen v_time1 en v_time2 meer dan v_duration_minutes + v_slack_minutes is, zo ja dan is het gat groot genoeg en voldoet ie (oke).
|
|
-- Wanneer v_time1 NULL is, betekent dit oneindig veel ruimte, en is het resultaat per defintie oke is.
|
|
-- Wanneer v_time2 NULL is, betekent dit oneindig veel ruimte, en is het resultaat per defintie oke is.
|
|
-- Wanneer een klus korter dan een werkdag duurt, dan gaan we de klus niet op meerdere werkdagen splitsen, we willen 1x de afspraak, deelafspraken zijn niet gewenst.
|
|
CREATE OR REPLACE FUNCTION marx_free_space
|
|
(v_res_deel_key IN NUMBER,
|
|
v_time1 IN DATE,
|
|
v_time2 IN DATE,
|
|
v_duration_minutes IN NUMBER,
|
|
v_slack_minutes IN NUMBER
|
|
)
|
|
RETURN NUMBER
|
|
AS
|
|
v_free NUMBER(1); -- 0 is niet free (not oke), 1 is wel free (oke)
|
|
l_working_minutes NUMBER(10);
|
|
l_workingday NUMBER(10);
|
|
l_vanaf_res_t1 DATE;
|
|
l_tot_res_t2 DATE;
|
|
BEGIN
|
|
BEGIN
|
|
v_free := 0;
|
|
l_vanaf_res_t1 := marx_get_res_t1(v_res_deel_key, v_time1); -- Starttijd vd dag
|
|
l_tot_res_t2 := marx_get_res_t2(v_res_deel_key, v_time1); -- Eindtijd vd dag
|
|
|
|
IF (ROUND((24*60*(l_tot_res_t2 - l_vanaf_res_t1))) >= (v_duration_minutes + v_slack_minutes))
|
|
THEN
|
|
-- De klus kan op 1 dag, we willen alleen een moment goedvinden als genoeg ruimte op die dag er is, m.a.w mag op meerdere dagen vinden we niet goed
|
|
-- Dus we willen alleen oke teruggeven als v_time1 IN DATE, v_time2 IN DATE op dezelfde dag liggen, EN (AND) het gat (tijd ertussen) voldoende groot is
|
|
|
|
-- Let op: omdat v_time2 kan leeg zijn, maximeren we deze op l_tot_res_t2, en we nemen de kleinste tijd (of eindtijd vd dag en anders de reservering van deze dag als die eerder is)
|
|
IF ROUND((24*60*(LEAST(COALESCE(v_time2, l_tot_res_t2), l_tot_res_t2) - v_time1))) >= (v_duration_minutes + v_slack_minutes)
|
|
THEN
|
|
-- Gat is ruim voldoende --> oke
|
|
v_free := 1;
|
|
END IF;
|
|
ELSE
|
|
-- Klus duurt langer dan een werkdag, we kunnen de klus wel splitsen op meerdere werkdagen...
|
|
-- Dat kan alleen als v_time2 niet vandaag, maar morgen, of nog later is, anders is er ook geen ruimte qua tijd, en kunnen we meteen stoppen.
|
|
-- Of als v_time2 NULL is (oneindige ruimte), dan kunnen we ook door gaan
|
|
IF v_time2 IS NULL OR TRUNC(v_time2) > TRUNC(v_time1)
|
|
THEN
|
|
l_working_minutes := ROUND(24*60*(l_tot_res_t2 - v_time1));
|
|
-- Klus pas niet op 1 werkdag, dan recursief aanroepen met morgen vanaf start dag, bij v_duration halen we de gewerkte uren (minuten) van vandaag (tot aan einde vd dag) eraf
|
|
l_vanaf_res_t1 := marx_get_res_t1(v_res_deel_key, v_time1 + 1);
|
|
|
|
v_free := marx_free_space(v_res_deel_key, l_vanaf_res_t1, v_time2, v_duration_minutes - l_working_minutes, v_slack_minutes);
|
|
END IF;
|
|
END IF;
|
|
EXCEPTION
|
|
WHEN NO_DATA_FOUND
|
|
THEN
|
|
v_free := 0;
|
|
WHEN TOO_MANY_ROWS
|
|
THEN
|
|
v_free := 0;
|
|
END;
|
|
RETURN v_free;
|
|
END;
|
|
/
|
|
|
|
|
|
--MARX#70053 Mareon Premium Groene Planningen: plannen met geografische optimalisatie
|
|
CREATE OR REPLACE FUNCTION marx_pi
|
|
RETURN NUMBER
|
|
AS
|
|
BEGIN
|
|
RETURN acos(-1);
|
|
END;
|
|
/
|
|
|
|
CREATE OR REPLACE FUNCTION marx_deg2rad(p_deg IN NUMBER)
|
|
RETURN NUMBER
|
|
AS
|
|
BEGIN
|
|
RETURN ROUND(p_deg * (marx_pi()/180), 20);
|
|
END;
|
|
/
|
|
|
|
-- Gebaseerd op https://en.wikipedia.org/wiki/Haversine_formula
|
|
CREATE OR REPLACE FUNCTION marx_dist_latlon_2_km(p_lat1 IN NUMBER,p_lon1 IN NUMBER, p_lat2 IN NUMBER, p_lon2 IN NUMBER)
|
|
RETURN NUMBER
|
|
AS
|
|
v_earth_R NUMBER(10) := 6371; -- Radius of the earth in km
|
|
dLat NUMBER(30,20);
|
|
dLon NUMBER(30,20);
|
|
a NUMBER(30,20);
|
|
c NUMBER(30,20);
|
|
d NUMBER(30,20);
|
|
BEGIN
|
|
dLat := marx_deg2rad(p_lat2-p_lat1); -- marx_deg2rad below
|
|
dLon := marx_deg2rad(p_lon2-p_lon1);
|
|
a := ROUND(
|
|
sin(dLat/2) * sin(dLat/2) +
|
|
cos(marx_deg2rad(p_lat1)) * cos(marx_deg2rad(p_lat2)) *
|
|
sin(dLon/2) * sin(dLon/2), 20);
|
|
c := ROUND(2 * atan2(sqrt(a), sqrt(1-a)), 20);
|
|
d := ROUND(v_earth_R * c, 20); -- Distance in km
|
|
RETURN d;
|
|
END;
|
|
/
|
|
|
|
-- Check of de lat-long coordinaten x en y wel of niet in het werkgebied van de persoon valt, gegeven de datum.
|
|
-- Controle van in de tabel inzetbaarheid 'prs_perslid_inzetbaar', als prs_perslid_inzetbaar_plaats_x en prs_perslid_inzetbaar_plaats_y en prs_perslid_inzetbaar_radius (uitgedrukt in KILOMETERS) op de dag van perslid BEIDEN zijn gevuld,
|
|
-- dan gaat we checken, en anders beschouwen we dat als 'er is geen specifiek werkgebied aangegeven' waarmee wordt gezegd: elke plaats is OKE (dus dan retoureert deze functie de waarde 1)
|
|
-- Dus indien BEIDE velden prs_perslid_inzetbaar_plaats_x en prs_perslid_inzetbaar_plaats_y zijn gevuld, gaan we controleren of de coordinaten in het werkgebied vallen.
|
|
-- Resultaat: 0 (=nee) of 1 (=ja)
|
|
CREATE OR REPLACE FUNCTION marx_coord_within_perslid_area(p_x IN NUMBER, p_y IN NUMBER, p_prs_perslid_key IN NUMBER, p_datum IN DATE)
|
|
RETURN NUMBER
|
|
AS
|
|
v_perslid_inzetbaar_plaats_x NUMBER(16,6);
|
|
v_perslid_inzetbaar_plaats_y NUMBER(16,6);
|
|
v_perslid_inzetbaar_radius NUMBER(6);
|
|
BEGIN
|
|
IF p_x IS NULL OR p_y IS NULL
|
|
THEN
|
|
-- Geen coordinaten bekend, dan kunnen we geen geo-check doen, en is (beschouwen we) alles oke.
|
|
RETURN 1;
|
|
END IF;
|
|
|
|
SELECT prs_perslid_inzetbaar_plaats_x, prs_perslid_inzetbaar_plaats_y, prs_perslid_inzetbaar_radius
|
|
INTO v_perslid_inzetbaar_plaats_x, v_perslid_inzetbaar_plaats_y, v_perslid_inzetbaar_radius
|
|
FROM prs_perslid_inzetbaar pi
|
|
WHERE pi.prs_perslid_key = p_prs_perslid_key
|
|
AND pi.prs_perslid_inzetbaar_dag = to_char(p_datum,'D') - 1;
|
|
|
|
IF v_perslid_inzetbaar_plaats_x IS NOT NULL AND v_perslid_inzetbaar_plaats_y IS NOT NULL AND v_perslid_inzetbaar_radius IS NOT NULL
|
|
THEN
|
|
-- v_perslid_inzetbaar_radius wordt in meters bewaard, dus met factor 1000 gaan we vergelijken op meters...
|
|
IF 1000* marx_dist_latlon_2_km(p_x, p_y, v_perslid_inzetbaar_plaats_x, v_perslid_inzetbaar_plaats_y) <= v_perslid_inzetbaar_radius
|
|
THEN
|
|
RETURN 1;
|
|
ELSE
|
|
RETURN 0;
|
|
END IF;
|
|
ELSE
|
|
RETURN 1;
|
|
END IF;
|
|
EXCEPTION
|
|
WHEN NO_DATA_FOUND
|
|
THEN RETURN 1;
|
|
END;
|
|
/
|
|
|
|
|
|
|
|
|
|
-- FUNCTION marx_are_you_free
|
|
-- "Mister Humphries are you free"? ;-)
|
|
-- Check of van bedrijf v_bedrijf_key een contactpersoon/een poppetje met expertise/competentie volgens v_competentie_code
|
|
-- op datum v_date de klus van v_duration_minutes minuten kan uitvoeren, beginnend tussen tijdtip v_starttime1 en v_starttime2
|
|
|
|
-- Parameters zijn allen verplicht:
|
|
-- v_bedrijf_key, moet gevuld zijn, alle contactpersonen met gekoppelde perslid binnen dit bedrijf doen mee in de speurtocht naar vrije/geschikte kandidaten..
|
|
-- v_competentie_code: gevuld met b.v. ELE (Elektricien), dan alleen op zoek naar personen die ELE zijn, andere codes zijn LOO, SCH, STU, OVE etc
|
|
-- v_starttime1, startmoment van de klus niet eerder dan dit tijdstip
|
|
-- v_starttime2, startmoment van de klus niet later dan dit tijdstip
|
|
-- v_duration_minutes, de duur in minuten hoe lang de klus/opdracht duurt, past dat in het planbord bij betreffende persoon (Humphries)?
|
|
-- v_slack_minutes, buffer (in minuten) die voor en na een planning (reservering) die nodig is t.b.v. bijvoorbeeld reistijd. (schoonmaaktijd bij ruimten).
|
|
|
|
-- En 2 nieuwe parameters agv MARX#70053 Mareon Premium Groene Planningen: plannen met geografische optimalisatie:
|
|
-- v_lat, indien niet gevuld, dan geen LAT-coordinaten van Maintenance-locatie bekend
|
|
-- v_lng, indien niet gevuld, dan geen LONG-coordinaten van Maintenance-locatie bekend
|
|
-- indien v_lat en v_lng wel gevuld, dan gaan we kijken of bedrijf wel rechten heeft cq. de module "Mareon Premium Groene Planningen" heeft anageschaft,
|
|
-- en zo ja, dan ook controleren of planvoorstel in geo-gebied van betreffende vakman valt.
|
|
|
|
-- MARX#75600 Mareon Groene Planning: Aansturing gebiedsoptimalisatie vanuit opdrachtgever
|
|
-- en nog optionele parameter (string) v_region_id, mogelijk vanuit Tobias gevuld (C20 in de praktijk) en alleen indien opdrachtnemer Groene Planning heeft aanstaan, anders is deze NULL.
|
|
-- indien gevuld dan wordt deze doorgegeven aan functie 'marx_are_you_free', zodat alleen de personen icm dagen in aanmerking komen die deze region-id in Mareon hebben geregsitreerd (via prs_perslid_inzetbaar)
|
|
|
|
-- MARX#75755 Registratie bij vakman voor welke opdrachtgever(s) deze werkzaamheden uitvoert
|
|
-- Nieuwe parameter v_woco_key is nodig, om te kijken of medewerker voor die woco inzetbaar is.
|
|
|
|
--------------
|
|
|
|
-- Return: eerste passende res_deel_key met daarbij de start-tijd.
|
|
|
|
CREATE OR REPLACE FUNCTION marx_are_you_free
|
|
(v_woco_key IN NUMBER,
|
|
v_bedrijf_key IN NUMBER,
|
|
v_competentie_code IN VARCHAR2,
|
|
v_start_datetime1 IN DATE,
|
|
v_start_datetime2 IN DATE,
|
|
v_duration_minutes IN NUMBER,
|
|
v_slack_minutes IN NUMBER,
|
|
v_lat IN NUMBER,
|
|
v_lng IN NUMBER,
|
|
v_region_id IN VARCHAR2
|
|
)
|
|
RETURN VARCHAR2
|
|
AS
|
|
-- Alle res_delen bij bedrijf (leverancier) 'v_bedrijf_key' met functie 'v_competentie_code' waarbij er geen omvattende (= eerdere starttijd en latere einddtijd) resevering op dat res_deel bestaat (die niet vervallen is)
|
|
-- Toevoeging MARX#70053 Mareon Premium Groene Planningen: plannen met geografische optimalisatie. We gaan eerst de vakmannen proberen die het kleinste werkgebied hebben (als die er is, anders maakt volgorde niet uit/dont care)
|
|
-- Dat maakt dat eerst vakmannen met het kleinste werkgebied worden gekozen, en als dat niet lukt, dan gaan we verder zoeken naar grotere (omvattende) werkgebieden...
|
|
CURSOR free_perslids
|
|
IS
|
|
SELECT DISTINCT d.res_deel_key, p.prs_perslid_key, pi.prs_perslid_inzetbaar_radius
|
|
FROM res_deel d, prs_perslid p, prs_bedrijfdienstlocatie bdl, prs_dienst di, prs_contactpersoon cp, prs_perslid_inzetbaar pi
|
|
WHERE d.res_deel_verwijder IS NULL
|
|
AND d.res_prs_perslid_key = p.prs_perslid_key
|
|
AND p.prs_perslid_verwijder IS NULL
|
|
AND COALESCE(bdl.prs_bedrijf_voor_key, v_woco_key) = v_woco_key
|
|
AND di.prs_dienst_key = bdl.prs_dienst_key
|
|
AND di.prs_dienst_hint = UPPER(v_competentie_code)
|
|
AND bdl.prs_perslid_key = p.prs_perslid_key
|
|
AND cp.prs_perslid_key = p.prs_perslid_key
|
|
AND cp.prs_contactpersoon_verwijder IS NULL
|
|
AND cp.prs_bedrijf_key = v_bedrijf_key
|
|
AND NOT EXISTS (SELECT 'x' FROM res_rsv_ruimte rr, res_rsv_deel rd
|
|
WHERE rr.res_rsv_ruimte_key = rd.res_rsv_ruimte_key
|
|
AND rr.res_rsv_ruimte_verwijder IS NULL
|
|
AND rd.res_deel_key = d.res_deel_key
|
|
AND rd.res_rsv_deel_verwijder IS NULL
|
|
AND rr.res_rsv_ruimte_van <= v_start_datetime1
|
|
AND rr.res_rsv_ruimte_tot >= v_start_datetime2
|
|
AND rr.res_status_fo_key <> 4
|
|
)
|
|
AND p.prs_perslid_key = pi.prs_perslid_key (+)
|
|
AND to_char(v_start_datetime1,'D') - 1 = pi.prs_perslid_inzetbaar_dag (+)
|
|
AND UPPER(COALESCE(pi.prs_perslid_inzetbaar_plaats, v_region_id, 'x')) = UPPER(COALESCE(v_region_id, pi.prs_perslid_inzetbaar_plaats, 'x'))
|
|
ORDER BY pi.prs_perslid_inzetbaar_radius;
|
|
|
|
|
|
v_free VARCHAR2(100);
|
|
l_zoeken_vanaf_starttijd DATE;
|
|
l_next_reservering_starttime DATE;
|
|
l_check_area_is_oke NUMBER(1);
|
|
BEGIN
|
|
BEGIN
|
|
v_free := NULL;
|
|
-- Beschikbaar bij een persoon (object) als:
|
|
-- 1. er geen reservering bestaat die geheel de starttijden overlappen, dus er mag geen res bestaan die voor v_starttime1 begint en na v_starttime2 eindigt (dan is de persoon al bezet) --> Dit doet cursor free_perslids
|
|
-- 2. er een gat van minimaal v_duration_minutes minuten te vinden is tussen vanaf v_starttime1 en v_starttime2
|
|
-- 3. dat gat vanaf de vorige bestaande reservering tot de eerst volgende bestaande reservering minimaal v_slack_minutes + v_duration_minutes + v_slack_minutes is.
|
|
|
|
-- 1.geeft alle personen (objecten) die geen reservering hebben die starttijden geheel overlapt
|
|
|
|
FOR rec IN free_perslids
|
|
LOOP
|
|
BEGIN
|
|
-- First of all, eerst checken of dit record op deze dag wel voldoet aan geografisch gebied, anders kunnen we deze gewoon skippen en is uitgebreid zoeken niet nodig.
|
|
-- Hiervoor is het dan wel nodig dat de leverancier Mareon Premium Groene Planningen heeft afgenomen, dat gaan we uiteraard eerst checken, want anders gaan we de check op geografische voorwaarde skippen...
|
|
-- Default is daarom 1
|
|
l_check_area_is_oke := 1;
|
|
IF marx_bedrijf_auth_4_greenplan(v_bedrijf_key) = 1 AND v_lat is NOT NULL AND v_lng IS NOT NULL
|
|
THEN
|
|
-- Oke, leverancier heeft Mareon Groene Planning, en coordinaten zijn bekend (not null), dan nu checken...
|
|
l_check_area_is_oke := marx_coord_within_perslid_area(v_lat, v_lng, rec.prs_perslid_key, v_start_datetime1);
|
|
END IF;
|
|
|
|
-- Als l_check_area_is_oke is waarde 0, dan heeft LEV deze module afgenomen en voldoet de vakman niet aan GEO-voorwaarde op die dag, en kunnen we die skippen, als waarde 1 dan wel kijken naar ruimte in zijn agenda...
|
|
IF l_check_area_is_oke = 1
|
|
THEN
|
|
-- Oke, aan GEO-voorwaarde wordt nu voldaan (of leverancier heeft dit niet afgenomen), we gaan nu in de agenda van betreffende vakman naar de vrije ruimte zoeken...
|
|
|
|
-- Zoek naar de dichts bijzijnde reservering voor perslid (res_deel) voorafgaande aan de v_start_datetime1 en die ook een eindtijd heeft na v_start_datetime1 (en die is weer voor v_start_datetime2, anders zit die niet in deze cursor/loop)
|
|
-- Is die er niet, dan beginnen we met zoeken vanaf v_start_datetime1.
|
|
-- Is die er wel, dan beginnen we met zoeken vanaf de eindtijd van de gevonden reservering.
|
|
-- Zijn er hiervan meerdere (wat op zich niet kan) dan zoeken we vanaf de max(eindtijd).
|
|
l_zoeken_vanaf_starttijd := marx_get_fromdatetime(rec.res_deel_key, v_start_datetime1, v_start_datetime2, v_slack_minutes);
|
|
-- Zolang de vanaf-tijd nog voor de uiterlijke starttijd (v_start_datetime2) zit, duiken we de loop in....
|
|
WHILE (l_zoeken_vanaf_starttijd < v_start_datetime2) AND (v_free IS NULL)
|
|
LOOP
|
|
-- Zoek in de periode tot aan v_start_datetime2 naar een (of het eerste) gat met een duur van minimaal v_duration_minutes + v_slack_minutes minuten, is die er gevonden,
|
|
-- dan voldoet deze res_deel_key, en zetten we v_free op res_deel_key met de startdatum/tijd waarop gat aanwezig is.
|
|
-- We zoeken de eerst volgende (in tijd gezien) reservering, als we die niet vonden, is er een oneindig gat, maar er moet wel passen qua duur tot aan einde vd dag
|
|
l_next_reservering_starttime := marx_get_next_res_starttijd(rec.res_deel_key, l_zoeken_vanaf_starttijd);
|
|
IF marx_free_space(rec.res_deel_key, l_zoeken_vanaf_starttijd, l_next_reservering_starttime, v_duration_minutes, v_slack_minutes) = 1
|
|
THEN
|
|
v_free := rec.res_deel_key || ';' || to_char(l_zoeken_vanaf_starttijd,'yyyy-mm-dd hh24:mi:ss');
|
|
ELSE
|
|
-- l_zoeken_vanaf_starttijd := marx_get_next_res_eindtijd(rec.res_deel_key, l_zoeken_vanaf_starttijd, v_slack_minutes);
|
|
l_zoeken_vanaf_starttijd := marx_get_fromdatetime(rec.res_deel_key, l_next_reservering_starttime, v_start_datetime2, v_slack_minutes);
|
|
END IF;
|
|
END LOOP;
|
|
END IF;
|
|
-- Zodra er een vrij beschikbaar moment is gevonden (v_free is niet meer NULL) dan uit de loop springen...
|
|
IF v_free IS NOT NULL
|
|
THEN EXIT;
|
|
END IF;
|
|
END;
|
|
END LOOP;
|
|
|
|
EXCEPTION
|
|
WHEN NO_DATA_FOUND
|
|
THEN
|
|
v_free := NULL;
|
|
WHEN TOO_MANY_ROWS
|
|
THEN
|
|
v_free := NULL;
|
|
END;
|
|
RETURN v_free;
|
|
END;
|
|
/
|
|
|
|
|
|
|
|
|
|
|
|
-- FUNCTION marx_get_planproposals
|
|
-- Levert maximaal v_max_options aan vrije (beschikbare) planvoorstellen op van een leverancier (v_bedrijf_key) van personen die voldoen aan functieprofiel (v_competentie_code) in de periode v_date_start tot en met v_date_end, rekening houdend
|
|
-- met eventuele voorkeursdagen/(start)tijden en waarin de werkzaamheden een duur van v_duration_minutes minuten hebben en moet passen.
|
|
-- Parameters:
|
|
-- v_bedrijf_key, moet gevuld zijn, alle contactpersonen met gekoppelde perslid binnen dit bedrijf doen mee in de speurtocht naar vrije/geschikte kandidaten..
|
|
-- v_competentie_code, indien gevuld met b.v. ELE (Elektricien) (of LOO, SCH, STU...), dan alleen op zoek naar personen die ELE zijn, indien gevuld met NULL, dan op zoek naar alle personen.
|
|
-- v_date_start, zoek naar geschikt moment vanaf deze datum, start vande datumrange, indien niet gevuld, dan vanaf vandaag
|
|
-- v_date_end, zoek naar geschikt moment t/m deze datum, einde van de datumrange, indien niet gevuld, dan t/m vandaag + 30 dagen.
|
|
-- v_mon_times, indien niet gevuld, dan doet maandag niet mee, indien gevuld dan alle maandagen binnen de tijdsippen afspeuren, formaat = '10:00:00-12:00:00;13:00:00-15:00:00;08:00:00-10:00:00;15:00:00-17:00:00;'
|
|
-- v_tue_times, indien niet gevuld, dan doet dinsdag niet mee, indien gevuld dan alle dinsdagen binnen de tijdsippen afspeuren,formaat = ...
|
|
-- v_wed_times, indien niet gevuld, dan doet woensdag niet mee, indien gevuld dan alle woensdagen binnen de tijdsippen afspeuren,
|
|
-- etc
|
|
-- etc
|
|
-- v_duration_minutes, duur die de werkzaamheden in beslag nemen, en een kandidaat-tijdsblok (op die datum waarin werkzaamheden beginnen) moet voldoende aan vrije ruimte in minuten hebben om als resultaat te voldoen.
|
|
-- v_slack_minutes, buffer (in minuten) die voor en na een planning (reservering) die nodig is t.b.v. bijvoorbeeld reistijd. (schoonmaaktijd bij ruimten).
|
|
-- v_max_options, maximum aantal te retourneren opties, indien leeg, dan is er geen maximum en wordt iedere mogelijkheid in het resultaat verwerkt.
|
|
|
|
-- En 2 nieuwe parameters agv MARX#70053 Mareon Premium Groene Planningen: plannen met geografische optimalisatie:
|
|
-- v_lat, indien niet gevuld, dan geen LAT-coordinaten van Maintenance-locatie bekend
|
|
-- v_lng, indien niet gevuld, dan geen LONG-coordinaten van Maintenance-locatie bekend
|
|
-- Beide parameters geven we door aan functie 'marx_are_you_free'.
|
|
|
|
-- MARX#75600 Mareon Groene Planning: Aansturing gebiedsoptimalisatie vanuit opdrachtgever
|
|
-- en nog optionele parameter (string) v_region_id, mogelijk vanuit Tobias gevuld (C20 in de praktijk) en alleen indien opdrachtnemer Groene Planning heeft aanstaan, anders is deze NULL.
|
|
-- indien gevuld dan wordt deze doorgegeven aan functie 'marx_are_you_free', zoda alleen de personen icm dagen in aanmerking komen die deze region-id in Mareon hebben geregsitreerd (via prs_perslid_inzetbaar)
|
|
|
|
-- ----------------------------
|
|
|
|
-- Resultaat: JSON met datumvoorstellen, dit zijn de bloktijden die voldoen, die worden geretourneerd:
|
|
-- Voorbeeld
|
|
-- [{ "planproposal": {"res_deel_key": "1234", "startdate": "2021-04-01", "starttime": "09:00", "enddate": "2021-04-01", "endtime": "12:00" } },
|
|
-- { "planproposal": {"res_deel_key": "1234", "startdate": "2021-04-01", "starttime": "13:00", "enddate": "2021-04-01", "endtime": "16:00" } },
|
|
-- { "planproposal": {"res_deel_key": "9876", "startdate": "2021-04-02", "starttime": "09:00", "enddate": "2021-04-02", "endtime": "12:00" } },
|
|
-- { "planproposal": {"res_deel_key": "9876", "startdate": "2021-04-05", "starttime": "13:00", "enddate": "2021-04-05", "endtime": "16:00" } },
|
|
-- ]
|
|
|
|
CREATE OR REPLACE FUNCTION marx_get_planproposals
|
|
(v_woco_key IN NUMBER,
|
|
v_bedrijf_key IN NUMBER,
|
|
v_competentie_code IN VARCHAR2,
|
|
v_date_start IN DATE,
|
|
v_date_end IN DATE,
|
|
v_mon_times IN VARCHAR2,
|
|
v_tue_times IN VARCHAR2,
|
|
v_wed_times IN VARCHAR2,
|
|
v_thu_times IN VARCHAR2,
|
|
v_fri_times IN VARCHAR2,
|
|
v_sat_times IN VARCHAR2,
|
|
v_sun_times IN VARCHAR2,
|
|
v_duration_minutes IN NUMBER,
|
|
v_slack_minutes IN NUMBER,
|
|
v_max_options IN NUMBER,
|
|
v_lat IN NUMBER,
|
|
v_lng IN NUMBER,
|
|
v_region_id IN VARCHAR2) RETURN VARCHAR2
|
|
AS
|
|
v_result VARCHAR2(4000);
|
|
v_result_inner VARCHAR2(4000);
|
|
l_aantal_options NUMBER(10);
|
|
l_date_start DATE;
|
|
l_stop NUMBER(1);
|
|
l_day_times VARCHAR2(4000);
|
|
l_time_frame VARCHAR2(1000);
|
|
l_datum_str VARCHAR2(100);
|
|
l_time1_str VARCHAR2(100);
|
|
l_time2_str VARCHAR2(100);
|
|
l_teller NUMBER(10);
|
|
l_datetime1 DATE;
|
|
l_datetime2 DATE;
|
|
l_free VARCHAR2(1000);
|
|
l_res_deel_key NUMBER(10);
|
|
|
|
BEGIN
|
|
v_result := '[]';
|
|
|
|
BEGIN
|
|
|
|
l_stop := 0;
|
|
-- We gaan zoeken in de periode vanaf v_date_start tot en met v_date_end, beide datums moeten wel vanaf vandaag (sysdate) zijn, dus in de toekomst, in verleden gaan we niet zoeken...
|
|
l_date_start := TRUNC(v_date_start);
|
|
IF l_date_start < TRUNC(SYSDATE)
|
|
THEN l_date_start := TRUNC(SYSDATE);
|
|
END IF;
|
|
|
|
l_aantal_options := 0;
|
|
l_day_times := NULL;
|
|
WHILE (l_aantal_options < v_max_options) AND (TRUNC(l_date_start) <= TRUNC(v_date_end))
|
|
LOOP
|
|
CASE
|
|
WHEN to_char(l_date_start,'D') = 1 THEN l_day_times := v_sun_times;
|
|
WHEN to_char(l_date_start,'D') = 2 THEN l_day_times := v_mon_times;
|
|
WHEN to_char(l_date_start,'D') = 3 THEN l_day_times := v_tue_times;
|
|
WHEN to_char(l_date_start,'D') = 4 THEN l_day_times := v_wed_times;
|
|
WHEN to_char(l_date_start,'D') = 5 THEN l_day_times := v_thu_times;
|
|
WHEN to_char(l_date_start,'D') = 6 THEN l_day_times := v_fri_times;
|
|
WHEN to_char(l_date_start,'D') = 7 THEN l_day_times := v_sat_times;
|
|
ELSE l_day_times := NULL;
|
|
END CASE;
|
|
-- b.v. l_day_times: '10:00:00-12:00:00;13:00:00-15:00:00;08:00:00-10:00:00;15:00:00-17:00:00;'
|
|
IF l_day_times IS NOT NULL
|
|
THEN
|
|
l_teller := 1;
|
|
fac.imp_getfield_nr (l_day_times, ';', l_teller, l_time_frame);
|
|
WHILE (l_time_frame IS NOT NULL) AND (l_aantal_options < v_max_options)
|
|
LOOP
|
|
-- b.v. l_time_frame: '10:00:00-12:00:00'
|
|
l_datum_str := to_char(l_date_start,'yyyy-mm-dd');
|
|
l_time1_str := SUBSTR(l_time_frame, 1, INSTR(l_time_frame,'-')-1);
|
|
l_time2_str := SUBSTR(l_time_frame, INSTR(l_time_frame,'-')+1);
|
|
|
|
l_datetime1 := to_date(l_datum_str || l_time1_str,'yyyy-mm-dd hh24:mi:ss');
|
|
l_datetime2 := to_date(l_datum_str || l_time2_str,'yyyy-mm-dd hh24:mi:ss');
|
|
IF l_datetime1 > SYSDATE AND l_datetime2 > SYSDATE
|
|
THEN
|
|
-- Timeframe kan niet in verleden liggen, die is niet meer (goed) te plannen ;-)
|
|
l_free := marx_are_you_free (v_woco_key, v_bedrijf_key, v_competentie_code, l_datetime1, l_datetime2, v_duration_minutes, v_slack_minutes, v_lat, v_lng, v_region_id);
|
|
IF (l_free IS NOT NULL) AND (l_aantal_options < v_max_options)
|
|
THEN
|
|
l_aantal_options := l_aantal_options + 1;
|
|
l_res_deel_key := fac.safe_to_number(SUBSTR(l_free, 1, INSTR(l_free,';')-1));
|
|
v_result_inner := v_result_inner || ', { "planproposal": {"res_deel_key": "' || l_res_deel_key || '", "startdate": "' || l_datum_str || '", "starttime": "' || l_time1_str || '", "enddate": "' || l_datum_str || '", "endtime": "' || l_time2_str || '" } }';
|
|
END IF;
|
|
END IF;
|
|
l_teller := l_teller + 1;
|
|
fac.imp_getfield_nr (l_day_times, ';', l_teller, l_time_frame);
|
|
END LOOP;
|
|
END IF;
|
|
l_date_start := l_date_start + 1;
|
|
END LOOP;
|
|
IF v_result_inner IS NOT NULL
|
|
THEN
|
|
v_result := '[' || SUBSTR(v_result_inner, 2) || ']';
|
|
END IF;
|
|
EXCEPTION
|
|
WHEN NO_DATA_FOUND
|
|
THEN
|
|
v_result := '[]';
|
|
WHEN TOO_MANY_ROWS
|
|
THEN
|
|
v_result := '[]';
|
|
END;
|
|
RETURN v_result;
|
|
END;
|
|
/
|
|
|
|
-- FUNCTION marx_set_planconfirmation
|
|
-- Parameters:
|
|
-- v_bedrijf_key, moet gevuld zijn, een van de contactpersonen met gekoppelde perslid binnen dit bedrijf wordt ingepland..
|
|
|
|
-- v_res_rsv_ruimte_key, moet gevuld zijn, is unieke id die leverancier in 1e call (planproposals) heeft teruggegeven aan caller, die deze in 2e call (nu dus) weer mee moet geven, waarmee de andere (STATIC) parameters (prs_bedrijf_key, v_duration_minutes, v_competentie_code) bepaald kunnen worden
|
|
-- v_ion_nr, is de unieke InkoopOpdrachtNummer van opdrachtgever die (later) wordt gestuurd, nu alvast in deze planning zodat deze alvast geregistreerd kan worden om later te koppelen aan de ION...
|
|
|
|
-- v_date_start, verplicht; de reservering moet op deze datum beginnen, formaat
|
|
-- v_time_start, verplicht; de reservering moet op/na dit tijdstip beginnen
|
|
-- v_time_end, verplicht; de reservering moet uiterlijk op dit tijdstip beginnen
|
|
|
|
-- Resultaat: JSON met datum/tijd confirmation retour, hier wordt als resultaat bij start- en enddate, maar ook bij start- en endtime, de momenten geretourneerd wanneer de klus daadwerkelijk start en eindigt, rekening houdende met duration, werktijden etc.
|
|
-- Voorbeeld
|
|
-- [{ "planproposal": {"res_deel_key": "1234", "startdate": "2021-04-01", "starttime": "10:45", "enddate": "2021-04-01", "endtime": "12:40" } }] (deze klus duurt 2 uur en hier wordt geen bloktijden maar de echte geplande datum/tijd weergegeven)
|
|
-- of ander voorbeeld:
|
|
-- [{ "planproposal": {"res_deel_key": "1234", "startdate": "2021-04-01", "starttime": "9:35", "enddate": "2021-04-02", "endtime": "11:35" } }] (deze klus duurt 12 uur, en gaat over 2 dagen, heeft dus niets met bloktijd van doen)
|
|
|
|
|
|
CREATE OR REPLACE FUNCTION marx_set_planconfirmation
|
|
(v_woco_key IN NUMBER,
|
|
v_bedrijf_key IN NUMBER,
|
|
v_res_rsv_ruimte_key IN NUMBER,
|
|
v_ion_nr IN VARCHAR2,
|
|
v_date_start IN DATE,
|
|
v_time_start IN VARCHAR2,
|
|
v_time_end IN VARCHAR2
|
|
) RETURN VARCHAR2
|
|
AS
|
|
v_result VARCHAR2(4000);
|
|
l_date_start DATE;
|
|
l_datum_str VARCHAR2(100);
|
|
l_datetime1 DATE;
|
|
l_datetime2 DATE;
|
|
l_free VARCHAR2(1000);
|
|
|
|
l_duration_minutes NUMBER(10);
|
|
l_slack_minutes NUMBER(10);
|
|
l_competentie_code VARCHAR2(1000);
|
|
|
|
l_res_deel_key NUMBER(10);
|
|
l_datetime_start DATE;
|
|
l_datetime_end DATE;
|
|
|
|
|
|
l_date_start_str VARCHAR2(100);
|
|
l_time_start_str VARCHAR2(100);
|
|
l_date_end_str VARCHAR2(100);
|
|
l_time_end_str VARCHAR2(100);
|
|
|
|
l_lat NUMBER(20,15);
|
|
l_lng NUMBER(20,15);
|
|
|
|
-- prs_perslid_inzetbaar_plaats
|
|
l_region_id VARCHAR(200);
|
|
|
|
v_result_inner VARCHAR2(4000);
|
|
BEGIN
|
|
v_result := '[]';
|
|
BEGIN
|
|
|
|
l_date_start := TRUNC(v_date_start);
|
|
IF l_date_start >= TRUNC(SYSDATE)
|
|
THEN
|
|
-- Startdatum moet niet in verleden liggen..
|
|
|
|
l_datum_str := to_char(l_date_start,'yyyy-mm-dd');
|
|
l_datetime1 := to_date(l_datum_str || v_time_start,'yyyy-mm-dd hh24:mi:ss');
|
|
l_datetime2 := to_date(l_datum_str || v_time_end,'yyyy-mm-dd hh24:mi:ss');
|
|
IF l_datetime1 > SYSDATE AND l_datetime2 > SYSDATE
|
|
THEN
|
|
-- Timeframe kan niet in verleden liggen, dan die is niet meer (goed) te plannen ;-)
|
|
|
|
SELECT 24*60*(res_rsv_ruimte_tot - res_rsv_ruimte_van), 0
|
|
INTO l_duration_minutes, l_slack_minutes
|
|
FROM res_rsv_ruimte
|
|
WHERE res_rsv_ruimte_key = v_res_rsv_ruimte_key;
|
|
|
|
SELECT MAX(res_kenmerkreservering_waarde)
|
|
INTO l_competentie_code
|
|
FROM res_kenmerkwaarde
|
|
WHERE res_kenmerk_key = 9
|
|
AND res_rsv_ruimte_key = v_res_rsv_ruimte_key
|
|
AND res_kenmerkwaarde_verwijder IS NULL;
|
|
|
|
SELECT fac.safe_to_number(MAX(res_kenmerkreservering_waarde))
|
|
INTO l_lat
|
|
FROM res_kenmerkwaarde
|
|
WHERE res_kenmerk_key = 6
|
|
AND res_rsv_ruimte_key = v_res_rsv_ruimte_key
|
|
AND res_kenmerkwaarde_verwijder IS NULL;
|
|
|
|
SELECT fac.safe_to_number(MAX(res_kenmerkreservering_waarde))
|
|
INTO l_lng
|
|
FROM res_kenmerkwaarde
|
|
WHERE res_kenmerk_key = 7
|
|
AND res_rsv_ruimte_key = v_res_rsv_ruimte_key
|
|
AND res_kenmerkwaarde_verwijder IS NULL;
|
|
|
|
-- MARX#75600 Mareon Groene Planning: Aansturing gebiedsoptimalisatie vanuit opdrachtgever
|
|
SELECT MAX(res_kenmerkreservering_waarde)
|
|
INTO l_region_id
|
|
FROM res_kenmerkwaarde
|
|
WHERE res_kenmerk_key = 10
|
|
AND res_rsv_ruimte_key = v_res_rsv_ruimte_key
|
|
AND res_kenmerkwaarde_verwijder IS NULL;
|
|
|
|
l_free := marx_are_you_free (v_woco_key, v_bedrijf_key, l_competentie_code, l_datetime1, l_datetime2, l_duration_minutes, l_slack_minutes, l_lat, l_lng, l_region_id);
|
|
IF (l_free IS NOT NULL)
|
|
THEN
|
|
-- Er is een passende planning, het is gelukt, we kunnen de confirmation wederom confirmen, Wel gaan we eerst de dummy proforma reservering goed zetten...
|
|
-- l_free bestaat uit string met 2 delen gescheiden door ";", en bevat res_deel_key en starttijd (in formaat yyyy-mm-dd hh24:mi:ss), dus b.v. "1234;2021-03-31 17:25:00"
|
|
l_res_deel_key := fac.safe_to_number(SUBSTR(l_free, 1, INSTR(l_free,';')-1));
|
|
l_datetime_start := fac.safe_to_date(SUBSTR(l_free, INSTR(l_free,';')+1), 'yyyy-mm-dd hh24:mi:ss');
|
|
l_datetime_end := marx_get_enddatetime(l_res_deel_key, l_datetime_start, l_duration_minutes);
|
|
|
|
l_date_start_str := to_char(l_datetime_start,'yyyy-mm-dd');
|
|
l_time_start_str := to_char(l_datetime_start,'hh24:mi:ss');
|
|
l_date_end_str := to_char(l_datetime_end,'yyyy-mm-dd');
|
|
l_time_end_str := to_char(l_datetime_end,'hh24:mi:ss');
|
|
|
|
--marx_put_res_dummy_2_real gaan we niet hier uitvoeren, maar ivm UPDATE actie (kan niet in functie) doen we dat iets later, in de asp.
|
|
--Daarom retourneren we alle gegevens (zoals res_deel_key en alle datum/tijden) via v_result....
|
|
|
|
v_result_inner := v_result_inner || ', { "planproposal": {"res_deel_key": "' || l_res_deel_key || '", "startdate": "' || l_date_start_str || '", "starttime": "' || l_time_start_str || '", "enddate": "' || l_date_end_str || '", "endtime": "' || l_time_end_str || '" } }';
|
|
END IF;
|
|
END IF;
|
|
END IF;
|
|
IF v_result_inner IS NOT NULL
|
|
THEN
|
|
v_result := '[' || SUBSTR(v_result_inner, 2) || ']';
|
|
END IF;
|
|
|
|
EXCEPTION
|
|
WHEN NO_DATA_FOUND
|
|
THEN
|
|
v_result := '[]';
|
|
WHEN TOO_MANY_ROWS
|
|
THEN
|
|
v_result := '[]';
|
|
END;
|
|
RETURN v_result;
|
|
END;
|
|
/
|
|
|
|
CREATE OR REPLACE FUNCTION marx_get_api_user(v_bedrijf_key IN NUMBER)
|
|
RETURN NUMBER
|
|
AS
|
|
prs_perslid_key NUMBER(10);
|
|
BEGIN
|
|
SELECT MIN(prs_perslid_key)
|
|
INTO prs_perslid_key
|
|
FROM mar_v_leverancier_api_perslid
|
|
WHERE prs_bedrijf_key = v_bedrijf_key;
|
|
RETURN prs_perslid_key;
|
|
EXCEPTION
|
|
WHEN NO_DATA_FOUND
|
|
THEN
|
|
RETURN NULL;
|
|
WHEN TOO_MANY_ROWS
|
|
THEN
|
|
RETURN NULL;
|
|
END;
|
|
/
|
|
|
|
|
|
|
|
-- Tijdelijk vasthouden van de gegevens van een planverzoek, zoals expertise (competentie), duur, maar ook voor generatie van een uniek planningsnummer t.b.v. de confirmation-bericht.
|
|
-- Er wordt een dummy res_reservering met dito res_rsv_ruimte en res_rsv_deel aangemaakt:
|
|
-- Voor woco v_woco_key, betreft prs_bedrijf_key van opdrachtgever (woco), die we moeten vastleggen zodat op een later moment, wanneer de opdracht (vanuit woco) wordt gestuurd, we de reservering uniek erbij kunnen vinden, samen met ION (die ook nog komt in PLNCFM
|
|
-- Voor leverancier v_bedrijf_key
|
|
-- Voor competentie v_competentie_code
|
|
-- Voor de duur van v_duration_minutes minuten
|
|
-- Onder uniek registratie-nummer v_res_rsv_ruimte_key, deze moet dus van te voren via NEW sequence worden opgehaald voordat deze procedure gebruikt kan worden, indien NULL wordt meegegeven, wordt deze door deze PROC bepaald.
|
|
-- LatLong worden hier bewaard (indien gevuld), zodat ze later in de 2e call bij de planbevestiging nog eens kunnen worden gebruikt tbv GEO-voorwaarde.
|
|
CREATE OR REPLACE PROCEDURE marx_put_dummy_res_reservering
|
|
(v_woco_key IN NUMBER,
|
|
v_bedrijf_key IN NUMBER,
|
|
v_competentie_code IN VARCHAR2,
|
|
v_duration_minutes IN NUMBER,
|
|
v_res_rsv_ruimte_key IN NUMBER,
|
|
v_lat IN NUMBER,
|
|
v_lng IN NUMBER,
|
|
v_region_id IN VARCHAR2)
|
|
AS
|
|
v_res_reservering_key NUMBER(10);
|
|
v_mld_opdr_key NUMBER(10);
|
|
v_res_rsv_ruimte_cvab_mode NUMBER(10);
|
|
v_res_activiteit_key NUMBER(10);
|
|
v_res_status_fo_key NUMBER(10);
|
|
v_res_rsv_ruimte_van DATE;
|
|
v_res_rsv_ruimte_tot DATE;
|
|
v_api_perslid_key NUMBER(10);
|
|
v_res_deel_key NUMBER(10);
|
|
v_res_rsv_deel_dirtlevel NUMBER(10);
|
|
l_res_rsv_ruimte_key NUMBER(10);
|
|
|
|
G_date_far_in_the_past VARCHAR2(10);
|
|
|
|
|
|
|
|
FUNCTION marx_get_first_res_deel(v_competentie_code IN VARCHAR2)
|
|
RETURN NUMBER
|
|
AS
|
|
res_deel_key NUMBER(10);
|
|
BEGIN
|
|
|
|
-- Zoek 'eerste' res_deel met juiste competentie van leverancier op
|
|
SELECT MIN(d.res_deel_key)
|
|
INTO res_deel_key
|
|
FROM res_deel d, prs_perslid p, prs_contactpersoon cp, prs_bedrijfdienstlocatie bdl, prs_dienst di
|
|
WHERE d.res_deel_verwijder IS NULL
|
|
AND d.res_prs_perslid_key = p.prs_perslid_key
|
|
AND p.prs_perslid_verwijder IS NULL
|
|
AND di.prs_dienst_key = bdl.prs_dienst_key
|
|
AND di.prs_dienst_hint = UPPER(v_competentie_code)
|
|
AND bdl.prs_perslid_key = p.prs_perslid_key
|
|
AND cp.prs_perslid_key = p.prs_perslid_key
|
|
AND cp.prs_contactpersoon_verwijder IS NULL
|
|
AND cp.prs_bedrijf_key = v_bedrijf_key;
|
|
|
|
RETURN res_deel_key;
|
|
|
|
EXCEPTION
|
|
WHEN NO_DATA_FOUND
|
|
THEN
|
|
RETURN NULL;
|
|
WHEN TOO_MANY_ROWS
|
|
THEN
|
|
RETURN NULL;
|
|
END;
|
|
|
|
----------- Start procedure ---
|
|
BEGIN
|
|
-- In Mareon is er 1 ruimte, die (helaas) tbv reserveringen aanwezig moet zijn (res_rsv_ruimte vereist deze).. om de res_delen te kunnen reserveren.
|
|
-- v_alg_ruimte_key := 3;
|
|
-- Sinds MARX#66033 - "Planbord voor resource-voorzieningen" is alg_ruimte voor personen niet meer nodig ;-)
|
|
-- Wel een mld_opdr_key, maar die is nog niet bekend, we doen een constante mld_opdr_key = 1 die niet meer actueel is.
|
|
v_mld_opdr_key := 1;
|
|
|
|
-- We bezorgen gewoon
|
|
v_res_rsv_ruimte_cvab_mode := 3;
|
|
-- De activiteit Planning in Mareon is key 11
|
|
v_res_activiteit_key := 11;
|
|
-- v_res_rsv_ruimte_van en v_res_rsv_ruimte_van zijn nu nog dummy, en plannen we ver in het verleden, op 24 jun 1968 12:00u en 13:00u
|
|
G_date_far_in_the_past := '24-06-1968';
|
|
v_res_rsv_ruimte_van := to_date(G_date_far_in_the_past || ' 12:00:00','dd-mm-yyyy hh24:mi:ss');
|
|
-- We verwerken de v_duration_minutes in v_res_rsv_ruimte_tot...
|
|
v_res_rsv_ruimte_tot := v_res_rsv_ruimte_van + (v_duration_minutes/(60*24));
|
|
-- We plannen hier als optie...
|
|
v_res_status_fo_key := 1;
|
|
v_res_rsv_deel_dirtlevel := 256;
|
|
|
|
|
|
v_api_perslid_key := marx_get_api_user(v_bedrijf_key);
|
|
IF v_api_perslid_key IS NOT NULL
|
|
THEN
|
|
v_res_deel_key := marx_get_first_res_deel(v_competentie_code);
|
|
END IF;
|
|
|
|
IF v_api_perslid_key IS NOT NULL AND v_res_deel_key IS NOT NULL
|
|
THEN
|
|
IF v_res_rsv_ruimte_key IS NULL
|
|
THEN
|
|
SELECT res_s_res_rsv_ruimte_key.nextval INTO l_res_rsv_ruimte_key from dual;
|
|
ELSE
|
|
l_res_rsv_ruimte_key := v_res_rsv_ruimte_key;
|
|
END IF;
|
|
|
|
INSERT INTO res_reservering (res_reservering_aanmaak) VALUES (SYSDATE) RETURNING res_reservering_key INTO v_res_reservering_key;
|
|
INSERT INTO res_rsv_ruimte(res_rsv_ruimte_key , res_reservering_key, res_rsv_ruimte_volgnr, res_rsv_ruimte_contact_key, res_rsv_ruimte_host_key, mld_opdr_key , res_rsv_ruimte_cvab_mode , res_activiteit_key , res_rsv_ruimte_van , res_rsv_ruimte_tot , res_status_fo_key)
|
|
VALUES(l_res_rsv_ruimte_key, v_res_reservering_key, 1, v_api_perslid_key , v_api_perslid_key , v_mld_opdr_key , v_res_rsv_ruimte_cvab_mode, v_res_activiteit_key, v_res_rsv_ruimte_van, v_res_rsv_ruimte_tot, v_res_status_fo_key);
|
|
INSERT INTO res_rsv_deel(res_deel_key , res_rsv_deel_aantal , res_status_bo_key, res_rsv_ruimte_key , res_rsv_deel_van , res_rsv_deel_tot , res_rsv_deel_dirtlevel)
|
|
VALUES(v_res_deel_key, 1 , 2 , l_res_rsv_ruimte_key, v_res_rsv_ruimte_van, v_res_rsv_ruimte_tot, v_res_rsv_deel_dirtlevel);
|
|
-- Woco-bedrijfskey ff bewaren in een hidden flexprop met key 2.
|
|
INSERT INTO res_kenmerkwaarde (res_kenmerk_key, res_rsv_ruimte_key, res_kenmerkreservering_waarde) VALUES(2, v_res_rsv_ruimte_key, v_woco_key);
|
|
-- Als LatLong niet LEEG zijn, dan ff bewaren in een betreffende hidden flexprop velden Plaats_X (key 6) en Plaats_Y (key 7)
|
|
IF v_lat IS NOT NULL AND v_lng IS NOT NULL
|
|
THEN
|
|
INSERT INTO res_kenmerkwaarde (res_kenmerk_key, res_rsv_ruimte_key, res_kenmerkreservering_waarde) VALUES(6, v_res_rsv_ruimte_key, ROUND(v_lat, 6));
|
|
INSERT INTO res_kenmerkwaarde (res_kenmerk_key, res_rsv_ruimte_key, res_kenmerkreservering_waarde) VALUES(7, v_res_rsv_ruimte_key, ROUND(v_lng, 6));
|
|
END IF;
|
|
-- MARX#70903: Competentie is niet meer 1-op-1 en daarmee niet meer te bepalen adhv perslid, daarom moeten we competentiecode nu wel onthouden!
|
|
IF v_competentie_code IS NOT NULL
|
|
THEN
|
|
INSERT INTO res_kenmerkwaarde (res_kenmerk_key, res_rsv_ruimte_key, res_kenmerkreservering_waarde) VALUES(9, v_res_rsv_ruimte_key, v_competentie_code);
|
|
END IF;
|
|
-- MARX#75600 Mareon Groene Planning: Aansturing gebiedsoptimalisatie vanuit opdrachtgever
|
|
IF v_region_id IS NOT NULL
|
|
THEN
|
|
INSERT INTO res_kenmerkwaarde (res_kenmerk_key, res_rsv_ruimte_key, res_kenmerkreservering_waarde) VALUES(10, v_res_rsv_ruimte_key, v_region_id);
|
|
END IF;
|
|
END IF;
|
|
END;
|
|
/
|
|
|
|
|
|
-- Opschoon PROC die (te) oude (met aanmaak-datum van meer dan "p_aantal_dagen" dagen geleden) dummy reserveringen die zijn achtergebleven, opruimt (=verwijdert)
|
|
--
|
|
CREATE OR REPLACE PROCEDURE marx_clean_dummy_reservering
|
|
(p_aantal_dagen IN NUMBER)
|
|
AS
|
|
G_date_far_in_the_past VARCHAR2(10);
|
|
----------- Start procedure ---
|
|
BEGIN
|
|
G_date_far_in_the_past := '24-06-1968';
|
|
DELETE FROM res_rsv_deel
|
|
WHERE TRUNC(res_rsv_deel_aanmaak) <= TRUNC(SYSDATE - p_aantal_dagen)
|
|
AND TRUNC(res_rsv_deel_van) = to_date(G_date_far_in_the_past,'dd-mm-yyyy');
|
|
|
|
DELETE FROM res_rsv_ruimte
|
|
WHERE TRUNC(res_rsv_ruimte_aanmaak) <= TRUNC(SYSDATE - p_aantal_dagen)
|
|
AND TRUNC(res_rsv_ruimte_van) = to_date(G_date_far_in_the_past,'dd-mm-yyyy');
|
|
|
|
DELETE FROM res_reservering rr
|
|
WHERE NOT EXISTS (SELECT 'X' FROM res_rsv_ruimte rrr WHERE rrr.res_reservering_key = rr.res_reservering_key);
|
|
|
|
COMMIT;
|
|
END;
|
|
/
|
|
|
|
-- MARX#75240 ORA-02291: Integriteitsbeperking (MARX.RES_R_RES_RSV_RUIMTE_KEY2) is geschonden
|
|
-- Is de reservering een dummy
|
|
-- Resulteert in 0 (=nee, false) of 1 (=ja, true)
|
|
CREATE OR REPLACE FUNCTION marx_is_reservering_dummy (v_res_rsv_ruimte_key IN NUMBER)
|
|
RETURN NUMBER
|
|
AS
|
|
G_date_far_in_the_past VARCHAR2(10);
|
|
v_aantal NUMBER(10);
|
|
|
|
BEGIN
|
|
G_date_far_in_the_past := '24-06-1968';
|
|
|
|
SELECT COUNT(*)
|
|
INTO v_aantal
|
|
FROM res_rsv_ruimte
|
|
WHERE res_rsv_ruimte_key = v_res_rsv_ruimte_key
|
|
AND TRUNC(res_rsv_ruimte_van) = to_date(G_date_far_in_the_past,'dd-mm-yyyy')
|
|
AND res_rsv_ruimte_verwijder IS NULL;
|
|
|
|
RETURN v_aantal;
|
|
END;
|
|
/
|
|
|
|
|
|
-- Past een (dummy) reservering aan naar een echte/bevestigde reservering (confirmation)
|
|
-- Er is namelijk inderdaad een plekje vrij, we gaan hem boeken door:
|
|
-- a) wanneer v_ion_nr (icm v_woco_key) nog NIET eerder gepland was (dus dit is een NIEUWE planning) --> de DUMMY "ProForma" res_reservering OM TE ZETTEN naar de juiste datum/tijdstip en persoon, dus van DUMMY naar REAL reservering
|
|
-- b) wanneer v_ion_nr (icm v_woco_key) nog WEL eerder gepland was (dus dit is aanpassing van BESTAANDE planning) --> de DUMMY "Proforma" verwijderen en de bestaande res_rsv_ruimte aanpassen (qua tijd maar ook evt qua persoon, kan nl iemand anders zijn geworden die past op nieuwe datum/tijd).
|
|
-- Het betreft in beide gevallen record v_res_rsv_ruimte en bijbehorende record v_res_rsv_deel, die worden op de nieuwe start en enddatum gezet, en ook op de nieuwe res_deel_key.
|
|
CREATE OR REPLACE PROCEDURE marx_put_res_dummy_2_real
|
|
( v_woco_key IN NUMBER,
|
|
v_res_rsv_ruimte_key IN NUMBER,
|
|
v_res_deel_key IN NUMBER,
|
|
v_date_start IN DATE,
|
|
v_date_end IN DATE,
|
|
v_time_start_vroegst IN VARCHAR2,
|
|
v_time_start_uiterlijk IN VARCHAR2,
|
|
v_ion_nr IN VARCHAR2)
|
|
AS
|
|
v_aantal NUMBER(10);
|
|
l_res_rsv_ruimte_key NUMBER(10);
|
|
l_mld_opdr_key NUMBER(10);
|
|
|
|
l_currentstatus NUMBER (10);
|
|
l_opdr_status_is_oke_to_change NUMBER (1);
|
|
|
|
v_mld_opdr_plandatum DATE;
|
|
v_prs_perslid_key NUMBER(10);
|
|
|
|
l_res_is_dummy NUMBER(10);
|
|
|
|
v_count_differences NUMBER (10);
|
|
v_do_send_opdr NUMBER (10);
|
|
v_do_send_changed_opdr NUMBER (10);
|
|
|
|
----------- Start procedure ---
|
|
BEGIN
|
|
-- Init...
|
|
l_mld_opdr_key := NULL;
|
|
|
|
-- MARX#75240: Robuuste check dat wel een dummy reservering wordt aangeroepen met v_res_rsv_ruimte_key
|
|
-- Oftewel alleen een dummy kan real worden gemaakt, een real die al real is doen we niets mee en skippen we
|
|
l_res_is_dummy := marx_is_reservering_dummy(v_res_rsv_ruimte_key);
|
|
IF l_res_is_dummy = 1
|
|
THEN
|
|
-- Check: is de dummy reservering door dezelfde woco gemaakt die 'm nu definitief kiest in PLNCFM-proces?
|
|
SELECT COUNT(*)
|
|
INTO v_aantal
|
|
FROM res_kenmerkwaarde
|
|
WHERE res_kenmerk_key = 2
|
|
AND res_rsv_ruimte_key = v_res_rsv_ruimte_key
|
|
AND res_kenmerkreservering_waarde = v_woco_key
|
|
AND res_kenmerkwaarde_verwijder IS NULL;
|
|
|
|
l_opdr_status_is_oke_to_change := 0;
|
|
IF v_aantal = 1
|
|
THEN
|
|
-- Eerst checken of hier voor deze ION (van deze woco) al eens eerder een geplande res_rsv_ruimte is aangemaakt, want dan moeten we deze bestaande res_rsv_ruimte aanpassen, en niet de DUMMY.
|
|
-- En als die niet bestaat, dus geheel nieuwe planning betreft, dan gaan we de DUMMY updaten.
|
|
|
|
-- Kortom: bepaal nu de l_res_rsv_ruimte_key: of een bestaande, of de dummy...
|
|
l_res_rsv_ruimte_key := marx_ion_already_planned (v_woco_key, v_ion_nr);
|
|
IF l_res_rsv_ruimte_key IS NULL
|
|
THEN
|
|
-- Bestaat nog niet, is dus geheel nieuw, we moeten de DUMMY aanpassen
|
|
l_res_rsv_ruimte_key := v_res_rsv_ruimte_key;
|
|
ELSE
|
|
-- Bestaat dus al wel, we moeten deze bestaande aanpassen, en de DUMMY verwijderen...
|
|
res.remove(v_res_rsv_ruimte_key);
|
|
END IF;
|
|
|
|
l_mld_opdr_key := marx_get_mld_opdr_via_ionr(v_woco_key, v_ion_nr);
|
|
IF l_mld_opdr_key IS NOT NULL
|
|
THEN
|
|
-- Opdracht bestaat al, kan zijn omdat:
|
|
-- 1. De planning (na een tijdje) door huurder gewijzigd wordt, en de opdracht inmiddels (al enige tijd) bestaat
|
|
-- 2. wat onwaarschijnlijk, maar timing-issue, dat de opdracht (net) iets eerder binnen is gekomen dan de bevestiging door huuder.
|
|
SELECT mld_statusopdr_key
|
|
INTO l_currentstatus
|
|
FROM mld_opdr
|
|
WHERE mld_opdr_key = l_mld_opdr_key;
|
|
-- Zie ook api_opdrsoap en/of mld.setopdrachtstatus (package-functie)
|
|
-- Allen bij lopende opdracht mag een wijziging, anders niet, dus alleen als status <> 1, 2, 6, 7, 9, dan is wijziging akkoord.
|
|
-- 1=Afgewezen / 2=Niet akkoord / 6=Afgemeld / 7=Verwerkt / 9=Afgerond
|
|
|
|
IF NOT (l_currentstatus = 1 OR l_currentstatus = 2 OR l_currentstatus = 6 OR l_currentstatus = 7 OR l_currentstatus = 9)
|
|
THEN
|
|
l_opdr_status_is_oke_to_change := 1;
|
|
END IF;
|
|
END IF;
|
|
|
|
|
|
IF (l_mld_opdr_key IS NULL) OR (l_opdr_status_is_oke_to_change = 1)
|
|
THEN
|
|
-- Opdracht mag gemuteerd worden, of is er nog niet...
|
|
-- We gaan de boel alleen aanpassen wanneer er nog geen opdracht is, of wel een opdracht is maar dan alleen als de opdracht nog wel muteerbaar mag worden (en niet gesloten/afgewezen is)
|
|
|
|
-- Wel even van de dummy de exacte begintijd (res_rsv_ruimte_van) en eindtijd (res_rsv_ruimte_tot) overnemen, die kan evt anders zijn geworden (tov de bestaande)
|
|
UPDATE res_rsv_ruimte
|
|
SET res_rsv_ruimte_van = v_date_start, res_rsv_ruimte_tot = v_date_end
|
|
WHERE res_rsv_ruimte_key = l_res_rsv_ruimte_key
|
|
AND res_rsv_ruimte_verwijder IS NULL;
|
|
UPDATE res_rsv_deel
|
|
SET res_rsv_deel_van = v_date_start, res_rsv_deel_tot = v_date_end, res_rsv_deel_dirtlevel = 0
|
|
WHERE res_rsv_ruimte_key = l_res_rsv_ruimte_key
|
|
AND res_rsv_deel_verwijder IS NULL;
|
|
|
|
IF v_res_deel_key IS NOT NULL
|
|
THEN
|
|
UPDATE res_rsv_deel
|
|
SET res_deel_key = v_res_deel_key
|
|
WHERE res_rsv_ruimte_key = l_res_rsv_ruimte_key
|
|
AND res_rsv_deel_verwijder IS NULL;
|
|
END IF;
|
|
|
|
IF v_ion_nr IS NOT NULL
|
|
THEN
|
|
-- Bestaat ionr al in flexprop (key 1), dan update, anders insert
|
|
SELECT COUNT(*)
|
|
INTO v_aantal
|
|
FROM res_kenmerkwaarde
|
|
WHERE res_kenmerk_key = 1
|
|
AND res_rsv_ruimte_key = l_res_rsv_ruimte_key
|
|
AND res_kenmerkwaarde_verwijder IS NULL;
|
|
|
|
IF v_aantal = 0
|
|
THEN
|
|
-- Zeer waarschijnlijk is dit de 1e keer (en dus nog niet eerder) dat huurder een afspraak maakt m.b.t. dit IONR
|
|
INSERT INTO res_kenmerkwaarde (res_kenmerk_key, res_rsv_ruimte_key, res_kenmerkreservering_waarde) VALUES(1, l_res_rsv_ruimte_key, v_ion_nr);
|
|
ELSE
|
|
-- Zeer waarschijnlijk is dit niet de 1e keer (en dus nog wel eerder) dat huurder een afspraak maakt m.b.t. dit IONR, en nu wellicht wil wijzigen.
|
|
UPDATE res_kenmerkwaarde
|
|
SET res_kenmerkreservering_waarde = v_ion_nr
|
|
WHERE res_kenmerk_key = 1
|
|
AND res_rsv_ruimte_key = l_res_rsv_ruimte_key
|
|
AND res_kenmerkwaarde_verwijder IS NULL;
|
|
END IF;
|
|
END IF;
|
|
|
|
IF l_mld_opdr_key IS NOT NULL
|
|
THEN
|
|
-- De opdracht (mld_opdr) bestaat dus al, we gaan:
|
|
-- 1. deze ook maar meteen officieel koppelen...
|
|
-- 2. status (van optie) naar definitief te zetten...
|
|
UPDATE res_rsv_ruimte
|
|
SET mld_opdr_key = l_mld_opdr_key, res_status_fo_key = 2
|
|
WHERE res_rsv_ruimte_key = l_res_rsv_ruimte_key
|
|
AND res_rsv_ruimte_verwijder IS NULL;
|
|
|
|
-- En ook de plandatum van de opdracht bijwerken, d.w.z. alleen als die anders is (dan ie was)...
|
|
SELECT mld_opdr_plandatum, prs_perslid_key
|
|
INTO v_mld_opdr_plandatum, v_prs_perslid_key
|
|
FROM mld_opdr
|
|
WHERE mld_opdr_key = l_mld_opdr_key;
|
|
v_count_differences := 0;
|
|
v_count_differences := mar_diff_date (v_mld_opdr_plandatum,
|
|
v_date_start,
|
|
l_mld_opdr_key,
|
|
v_prs_perslid_key,
|
|
'Plan(afspraak) datum',
|
|
'#ORDUPD');
|
|
UPDATE mld_opdr
|
|
SET mld_opdr_plandatum = v_date_start
|
|
WHERE mld_opdr_key = l_mld_opdr_key;
|
|
|
|
|
|
-- OPNIEUW opdracht versturen naar aannemer, indien:
|
|
-- 1. aannemer een technisch adres voor (dit type) opdracht heeft waarop de bon of (ketenstandaard)XML bericht op afgeleverd kan worden
|
|
-- 2. aannemer bij (ketenstandaard)-XML bericht wel premium aannemer is
|
|
-- 3. aannemer gewijzigde opdrachten wel wil/kan ontvangen, dit wordt vastgelegd in het kenmerk '$MAR_PUO_MODE' bij de leverancier (prs_kenmerk_key = 23)
|
|
-- 4. er wel wijzigingen zijn
|
|
|
|
-- Eerst punten 1 en 2, oftewel check of aannemer tech adres heeft voor deze opdracht(type) waarnaar opdrachten gestuurd kunnen worden
|
|
v_do_send_opdr := mar_send_mld_opdr_to_supplier (l_mld_opdr_key);
|
|
-- Daarna punt 3, wil/kan de aannemer ook de gewijzigde opdracht ontvangen.
|
|
v_do_send_changed_opdr := mar_check_resend_changed_opdr (l_mld_opdr_key);
|
|
IF v_do_send_opdr = 1 AND v_do_send_changed_opdr = 1 AND v_count_differences > 0
|
|
THEN
|
|
mar_resend_mld_opdr_2_lev (l_mld_opdr_key, 2);
|
|
END IF;
|
|
END IF;
|
|
|
|
IF v_date_start IS NOT NULL
|
|
THEN
|
|
-- Bestaat v_date_start al in flexprop (key 3), dan update, anders insert
|
|
SELECT COUNT(*)
|
|
INTO v_aantal
|
|
FROM res_kenmerkwaarde
|
|
WHERE res_kenmerk_key = 3
|
|
AND res_rsv_ruimte_key = l_res_rsv_ruimte_key
|
|
AND res_kenmerkwaarde_verwijder IS NULL;
|
|
|
|
IF v_aantal = 0
|
|
THEN
|
|
-- Zeer waarschijnlijk is dit de 1e keer (en dus nog niet eerder) dat huurder een afspraak maakt m.b.t. dit startdatum
|
|
INSERT INTO res_kenmerkwaarde (res_kenmerk_key, res_rsv_ruimte_key, res_kenmerkreservering_waarde) VALUES(3, l_res_rsv_ruimte_key, TO_CHAR(v_date_start,'DD-MM-YYYY'));
|
|
ELSE
|
|
-- Zeer waarschijnlijk is dit niet de 1e keer (en dus nog wel eerder) dat huurder een afspraak maakt m.b.t. dit startmoment tijdsblok, en nu wellicht wil wijzigen.
|
|
UPDATE res_kenmerkwaarde
|
|
SET res_kenmerkreservering_waarde = TO_CHAR(v_date_start,'DD-MM-YYYY')
|
|
WHERE res_kenmerk_key = 3
|
|
AND res_rsv_ruimte_key = l_res_rsv_ruimte_key
|
|
AND res_kenmerkwaarde_verwijder IS NULL;
|
|
END IF;
|
|
|
|
END IF;
|
|
|
|
IF v_time_start_vroegst IS NOT NULL
|
|
THEN
|
|
-- Bestaat v_time_start_vroegst al in flexprop (key 4), dan update, anders insert
|
|
SELECT COUNT(*)
|
|
INTO v_aantal
|
|
FROM res_kenmerkwaarde
|
|
WHERE res_kenmerk_key = 4
|
|
AND res_rsv_ruimte_key = l_res_rsv_ruimte_key
|
|
AND res_kenmerkwaarde_verwijder IS NULL;
|
|
|
|
IF v_aantal = 0
|
|
THEN
|
|
-- Zeer waarschijnlijk is dit de 1e keer (en dus nog niet eerder) dat huurder een afspraak maakt m.b.t. dit startmoment tijdsblok
|
|
INSERT INTO res_kenmerkwaarde (res_kenmerk_key, res_rsv_ruimte_key, res_kenmerkreservering_waarde) VALUES(4, l_res_rsv_ruimte_key, v_time_start_vroegst);
|
|
ELSE
|
|
-- Zeer waarschijnlijk is dit niet de 1e keer (en dus nog wel eerder) dat huurder een afspraak maakt m.b.t. dit startmoment tijdsblok, en nu wellicht wil wijzigen.
|
|
UPDATE res_kenmerkwaarde
|
|
SET res_kenmerkreservering_waarde = v_time_start_vroegst
|
|
WHERE res_kenmerk_key = 4
|
|
AND res_rsv_ruimte_key = l_res_rsv_ruimte_key
|
|
AND res_kenmerkwaarde_verwijder IS NULL;
|
|
END IF;
|
|
END IF;
|
|
|
|
IF v_time_start_uiterlijk IS NOT NULL
|
|
THEN
|
|
-- Bestaat v_time_start_uiterlijk al in flexprop (key 5), , dan update, anders insert
|
|
SELECT COUNT(*)
|
|
INTO v_aantal
|
|
FROM res_kenmerkwaarde
|
|
WHERE res_kenmerk_key = 5
|
|
AND res_rsv_ruimte_key = l_res_rsv_ruimte_key
|
|
AND res_kenmerkwaarde_verwijder IS NULL;
|
|
|
|
IF v_aantal = 0
|
|
THEN
|
|
-- Zeer waarschijnlijk is dit de 1e keer (en dus nog niet eerder) dat huurder een afspraak maakt m.b.t. dit eindmoment tijdsblok
|
|
INSERT INTO res_kenmerkwaarde (res_kenmerk_key, res_rsv_ruimte_key, res_kenmerkreservering_waarde) VALUES(5, l_res_rsv_ruimte_key, v_time_start_uiterlijk);
|
|
ELSE
|
|
-- Zeer waarschijnlijk is dit niet de 1e keer (en dus nog wel eerder) dat huurder een afspraak maakt m.b.t. dit startmoment tijdsblok, en nu wellicht wil wijzigen.
|
|
UPDATE res_kenmerkwaarde
|
|
SET res_kenmerkreservering_waarde = v_time_start_uiterlijk
|
|
WHERE res_kenmerk_key = 5
|
|
AND res_rsv_ruimte_key = l_res_rsv_ruimte_key
|
|
AND res_kenmerkwaarde_verwijder IS NULL;
|
|
END IF;
|
|
END IF;
|
|
|
|
END IF; -- Opdracht mag gemuteerd worden, of is er nog niet...
|
|
END IF; -- Check of dummy reservering door dezelfde woco gemaakt die 'm nu definitief kiest in PLNCFM-proces?
|
|
END IF; -- Check of het een dummy reservering betreft
|
|
COMMIT;
|
|
END;
|
|
/
|
|
|
|
|
|
|
|
|
|
|
|
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
|
|
|
|
|
|
|
-- Bij 1e aanmaak van opdracht (proces opdrachtverstrekking), indien er een officieuze reservering/planning bij de opdracht bestaat (= via flexprop, dan moet deze officieel nog gekoppeld worden.
|
|
|
|
CREATE OR REPLACE PROCEDURE marx_koppel_res_plan(v_mld_opdr_key IN NUMBER, v_prs_woco_key In NUMBER, v_ion_nr IN VARCHAR2)
|
|
AS
|
|
v_res_rsv_ruimte_key NUMBER(10);
|
|
----------- Start procedure ---
|
|
BEGIN
|
|
IF v_mld_opdr_key IS NOT NULL AND v_prs_woco_key IS NOT NULL AND v_ion_nr IS NOT NULL
|
|
THEN
|
|
SELECT MAX(rk.res_rsv_ruimte_key)
|
|
INTO v_res_rsv_ruimte_key
|
|
FROM res_kenmerkwaarde rk, res_kenmerkwaarde rk2
|
|
WHERE rk.res_kenmerkreservering_waarde = v_ion_nr
|
|
AND rk.res_kenmerk_key = 1
|
|
AND rk.res_kenmerkwaarde_verwijder IS NULL
|
|
AND rk2.res_kenmerkreservering_waarde = v_prs_woco_key
|
|
AND rk2.res_kenmerk_key = 2
|
|
AND rk2.res_kenmerkwaarde_verwijder IS NULL
|
|
AND rk.res_rsv_ruimte_key = rk2.res_rsv_ruimte_key;
|
|
|
|
IF v_res_rsv_ruimte_key IS NOT NULL
|
|
THEN
|
|
UPDATE res_rsv_ruimte rr
|
|
SET rr.mld_opdr_key = v_mld_opdr_key
|
|
WHERE rr.res_rsv_ruimte_key = v_res_rsv_ruimte_key
|
|
AND rr.res_rsv_ruimte_verwijder IS NULL;
|
|
END IF;
|
|
|
|
-- TODO: tracking-record erbij...
|
|
|
|
END IF;
|
|
END;
|
|
/
|
|
|
|
-- Rapportage van de vertaaltabel van vaardigheden (expertises) die leverancier kan instellen.
|
|
-- Elke vaardigheid (code) vanuit opdrachtgever kan worden vertaald naar de vaardigheid (code) die leverancier hanteert...
|
|
|
|
CREATE OR REPLACE VIEW marx_udr_vertaal_vaardigheden
|
|
(FCLT_3D_USER_KEY, code_opdrachtgever, code_opdrachtnemer)
|
|
AS
|
|
SELECT cp.prs_perslid_key, SUBSTR(fac_usrdata_upper, INSTR(fac_usrdata_upper,'|')+1), fac_usrdata_omschr
|
|
FROM fac_usrdata, prs_contactpersoon cp
|
|
WHERE fac_usrtab_key = 8
|
|
AND SUBSTR(fac_usrdata_upper, 1, INSTR(fac_usrdata_upper,'|')-1) = cp.prs_bedrijf_key
|
|
AND fac_usrdata_verwijder IS NULL
|
|
AND cp.prs_contactpersoon_verwijder IS NULL
|
|
AND cp.prs_perslid_key IS NOT NULL;
|
|
|
|
------ payload end ------
|
|
|
|
SET DEFINE OFF
|
|
BEGIN adm.systrackscriptId ('$Id$', 1); END;
|
|
/
|
|
|
|
COMMIT;
|
|
SET ECHO OFF
|
|
SPOOL OFF
|
|
SET DEFINE ON
|
|
PROMPT Logfile of this upgrade is: &fcltlogfile
|