From f90e366bea4a8d45f03fa00ba4fd6cb04f7c12b3 Mon Sep 17 00:00:00 2001 From: Norbert Wassink Date: Fri, 29 Oct 2021 14:46:43 +0000 Subject: [PATCH] DEMO#69040 -- demo_import_echange en demo_update_exchange toegevoegd tbv outlook koppeling svn path=/Customer/trunk/; revision=53543 --- DEMO/demo.sql | 2017 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 2017 insertions(+) diff --git a/DEMO/demo.sql b/DEMO/demo.sql index 414537624..f873e0da2 100644 --- a/DEMO/demo.sql +++ b/DEMO/demo.sql @@ -3933,11 +3933,779 @@ AS p_periode_tot IN DATE := NULL) RETURN NUMBER; PROCEDURE refreshscore(pUserKey IN NUMBER); + + -- Maakt afspraak met bezoekers aan, indien nodig + PROCEDURE setBezoekers(p_import_key IN NUMBER, + p_appt_id IN VARCHAR2, + p_recur_id IN VARCHAR2, + p_rsv_ruimte_key IN NUMBER); + + -- Haalt bestaande afspraak bij rsv_ruimte op, of maakt een nieuwe + FUNCTION getAfspraak (p_rsv_ruimte_key IN NUMBER, + p_createnew IN NUMBER) + RETURN NUMBER; + + -- Update of insert bezoeker met de juiste voorwaarden + PROCEDURE upsertBezoeker (p_import_key IN NUMBER, + p_afspraak_key IN NUMBER, + p_bezoekers_key IN NUMBER, + p_att_mail IN VARCHAR2, + p_att_name IN VARCHAR2, + p_perslid_key IN NUMBER, + p_afdeling_naam IN VARCHAR2); + + PROCEDURE upsertkenmerk_bez (p_kenmerk_key IN NUMBER, + p_bez_key IN NUMBER, + p_waarde IN VARCHAR2); + + PROCEDURE upsertkenmerk_res(p_kenmerk_key IN NUMBER, + p_rsv_ruimte_key IN NUMBER, + p_waarde IN VARCHAR2); + FUNCTION getOpstelling(p_room_id IN VARCHAR2) + RETURN NUMBER; + + PROCEDURE checkParking(p_bezoekers_key IN NUMBER); + + PROCEDURE set_ruimtes_clean(p_import_key IN NUMBER); END; / CREATE OR REPLACE PACKAGE BODY demo AS + -- Zorg dat de bezoekers bij de deelreservering matchen met de genodigden bij de appointment + -- - host niet toevoegen als bezoeker + -- - AMB-en SSCA-medewerkers met een badgenummer alleen in een genodigdenlijst + -- Afspraak aanmaken of verwijderen indien nodig + -- Bezoekers aanmaken, bijwerken of verwijderen zoals nodig + -- Als vergaderruimte op kantoorverdieping (OF-ruimte), dan geen bezoekers (alleen genodigdenlijst), + -- noch voorzieningen + -- - OF = res_disc 1485 "Vergaderruimtes nw A'dam" + -- - EXCO = res_disc 1505 "Vergaderzalen 9de PA's" + -- - MC = res_disc 1445 "Vergaderzalen NW Amsterdam" + -- TODO: nu worden voor appointments met meerdere zalen waarschijnlijk de attendees bij iedere + -- deelreservering toegevoegd. + -- KFSG#57950: Voor Schiphol geldt (voor enige locatie/catalogus/activiteit) alleen externen als + -- bezoeker (en eigen medewerkers in Genodigden-kenmerk?). + PROCEDURE setBezoekers(p_import_key IN NUMBER, + p_appt_id IN VARCHAR2, + p_recur_id IN VARCHAR2, + p_rsv_ruimte_key IN NUMBER) + IS + v_debug BOOLEAN := TRUE; + v_count NUMBER (10); + c_km_key_genodigden NUMBER (10) := 181; + + v_genodigden VARCHAR2 (4000); + v_afspraak_key NUMBER (10); + v_datum_old DATE; + v_eind_old DATE; + v_datum_new DATE; + v_eind_new DATE; + v_discipline_key NUMBER (10) := NULL; + + -- Alle bezoekers bij deze rsv_ruimte, die niet meer in het importbestand zitten + -- AKZA#38972: zorgen dat personen die als bezoeker aangemeld waren, maar nu 'slechts' genodigde zijn, ook verwijderd worden + -- En als we toch bezig zijn: ruimtes kunnen geen bezoekers meer zijn; ook die weggooien dus. + CURSOR c_del + IS + -- Niet meer in de import + SELECT a.res_rsv_ruimte_key, + kw.bez_kenmerkwaarde_waarde bez_email, + b.* + FROM bez_afspraak a, + bez_bezoekers b, + bez_kenmerkwaarde kw + WHERE a.res_rsv_ruimte_key = p_rsv_ruimte_key + AND b.bez_afspraak_key = a.bez_afspraak_key + AND kw.bez_bezoekers_key = b.bez_bezoekers_key + AND kw.bez_kenmerk_key = 1120 -- E-mailadres Exchange + AND kw.bez_kenmerkwaarde_verwijder IS NULL + AND NOT EXISTS (SELECT 1 + FROM demo_imp_exchange + WHERE UPPER(att_mail) = UPPER(kw.bez_kenmerkwaarde_waarde) ) + UNION ALL + -- Naam al aanwezig in lijst van genodigden + SELECT a.res_rsv_ruimte_key, + kw.bez_kenmerkwaarde_waarde bez_email, + b.* + FROM bez_afspraak a, + bez_bezoekers b, + bez_kenmerkwaarde kw, + res_kenmerkwaarde rkw + WHERE a.res_rsv_ruimte_key = p_rsv_ruimte_key + AND b.bez_afspraak_key = a.bez_afspraak_key + AND kw.bez_bezoekers_key = b.bez_bezoekers_key + AND kw.bez_kenmerk_key = 1120 -- E-mailadres Exchange + AND kw.bez_kenmerkwaarde_verwijder IS NULL + AND rkw.res_kenmerk_key = c_km_key_genodigden + AND rkw.res_kenmerkwaarde_verwijder IS NULL + AND rkw.res_rsv_ruimte_key = a.res_rsv_ruimte_key + AND rkw.res_kenmerkreservering_waarde LIKE '%'||b.bez_afspraak_naam||'%' + UNION ALL + -- Mailadres bekend als extern ID van ruimte + SELECT a.res_rsv_ruimte_key, + kw.bez_kenmerkwaarde_waarde bez_email, + b.* + FROM bez_afspraak a, + bez_bezoekers b, + bez_kenmerkwaarde kw + WHERE a.res_rsv_ruimte_key = p_rsv_ruimte_key + AND b.bez_afspraak_key = a.bez_afspraak_key + AND kw.bez_bezoekers_key = b.bez_bezoekers_key + AND kw.bez_kenmerk_key = 1120 -- E-mailadres Exchange + AND kw.bez_kenmerkwaarde_verwijder IS NULL + AND EXISTS (SELECT 1 + FROM res_ruimte + WHERE UPPER(res_ruimte_extern_id) = UPPER(kw.bez_kenmerkwaarde_waarde)); + + -- Voor iedere persoon kijken of dit een bekende AN-medewerker is en op welke locatie + -- Als mailadres deelnemer == mailadres organizer, dan negeren + -- Group by, zodat we voor mensen op AMB/SSCA (en AHO) alleen die werkplek overhouden (overige locaties leveren NULL) + -- AKZA#38968: ook badgenummer ophalen + CURSOR c_attendees + IS + SELECT att_mail, + COALESCE(prs_perslid_naam_full, att_name) att_name, + prs_perslid_key, + prs_afdeling_naam, + MAX(alg_locatie_key) alg_locatie_key, + MAX(alg_locatie_code) alg_locatie_code, + --badgenr, + bez_bezoekers_key + FROM ( + SELECT DISTINCT att_mail, att_name + FROM demo_imp_exchange + WHERE appt_id||'|'||recur_id = p_appt_id||'|'||p_recur_id + AND att_mail != organizer + AND NOT EXISTS (SELECT 1 + FROM res_ruimte + WHERE UPPER(res_ruimte_extern_id) = UPPER(att_mail) ) ) e + LEFT OUTER JOIN ( + SELECT p.prs_perslid_key, + p.prs_perslid_email, + pf.prs_perslid_naam_full, + --kl.prs_kenmerklink_waarde badgenr + a.prs_afdeling_naam, + l.alg_locatie_key, + l.alg_locatie_code + FROM prs_perslid p, + prs_v_perslid_fullnames pf, + --(SELECT * FROM prs_kenmerklink + -- WHERE prs_kenmerk_key = -1 -- Badgenummer (van medewerker) + -- AND prs_kenmerklink_niveau = 'P' + -- AND prs_kenmerklink_verwijder IS NULL) kl, + prs_afdeling a, + prs_perslidwerkplek pw, + prs_werkplek w, + alg_ruimte r, + alg_verdieping v, + alg_gebouw g, + (SELECT * FROM alg_locatie + WHERE alg_locatie_key = 41) l -- SHG - Schipholgebouw + WHERE p.prs_perslid_verwijder IS NULL + AND p.prs_perslid_email IS NOT NULL + --AND kl.prs_link_key(+) = p.prs_perslid_key + AND pf.prs_perslid_key = p.prs_perslid_key + AND a.prs_afdeling_key = p.prs_afdeling_key + AND pw.prs_perslid_key = p.prs_perslid_key + AND w.prs_werkplek_key = pw.prs_werkplek_key + AND r.alg_ruimte_key = w.prs_alg_ruimte_key + AND r.alg_ruimte_verwijder IS NULL + AND v.alg_verdieping_key = r.alg_verdieping_key + AND g.alg_gebouw_key = v.alg_gebouw_key + AND l.alg_locatie_key(+) = g.alg_locatie_key) p + ON UPPER(p.prs_perslid_email) = UPPER(att_mail) + LEFT OUTER JOIN ( + SELECT b.bez_bezoekers_key, + kw.bez_kenmerkwaarde_waarde email + FROM bez_afspraak a, + bez_bezoekers b, + bez_kenmerkwaarde kw + WHERE a.res_rsv_ruimte_key = p_rsv_ruimte_key + AND b.bez_afspraak_key = a.bez_afspraak_key + AND kw.bez_bezoekers_key = b.bez_bezoekers_key + AND kw.bez_kenmerk_key = 1120 -- E-mailadres Exchange + AND kw.bez_kenmerkwaarde_verwijder IS NULL) b + ON UPPER(b.email) = UPPER(att_mail) + GROUP BY att_mail, + att_name, + prs_perslid_key, + prs_perslid_naam_full, + prs_afdeling_naam, + --badgenr, + bez_bezoekers_key; + + BEGIN + v_genodigden := NULL; + + SELECT COUNT(*) + INTO v_count + FROM demo_imp_exchange + WHERE appt_id||'|'||recur_id = p_appt_id||'|'||p_recur_id + AND att_mail != organizer; + + IF (v_count = 0) + THEN + IF (v_debug) THEN + fac.imp_writelog (p_import_key, 'D', + p_rsv_ruimte_key, 'Geen gasten'); + END IF; + -- Lijst genodigden wissen + DELETE res_kenmerkwaarde + WHERE res_kenmerk_key = c_km_key_genodigden + AND res_rsv_ruimte_key = p_rsv_ruimte_key; + -- Afspraak wissen + v_afspraak_key := demo.getAfspraak(p_rsv_ruimte_key, 0); + IF v_afspraak_key IS NOT NULL + THEN + IF (v_debug) THEN + fac.imp_writelog (p_import_key, 'D', + p_rsv_ruimte_key, 'Afspraak verwijderen'); + END IF; + DELETE bez_afspraak + WHERE bez_afspraak_key = v_afspraak_key; + END IF; + ELSE + -- Niet-meer bekende attendees verwijderen + FOR rec IN c_del + LOOP + IF (v_debug) THEN + fac.imp_writelog (p_import_key, 'D', + p_rsv_ruimte_key, 'Bezoeker '||rec.bez_email||' verwijderen'); + END IF; + DELETE bez_kenmerkwaarde + WHERE bez_bezoekers_key = rec.bez_bezoekers_key; + + DELETE bez_bezoekers + WHERE bez_bezoekers_key = rec.bez_bezoekers_key; + END LOOP; + + FOR rec IN c_attendees + LOOP + -- Bepalen om wat voor soort ruimte het gaat (OF vs MC/EXCO) + IF (v_discipline_key IS NULL) + THEN + SELECT r.res_discipline_key + INTO v_discipline_key + FROM res_ruimte r, + res_ruimte_opstelling ro, + res_rsv_ruimte rr + WHERE rr.res_rsv_ruimte_key = p_rsv_ruimte_key + AND ro.res_ruimte_opstel_key = rr.res_ruimte_opstel_key + AND r.res_ruimte_key = ro.res_ruimte_key; + IF (v_debug) THEN + fac.imp_writelog (p_import_key, 'D', + p_rsv_ruimte_key, 'Discipline = '||v_discipline_key); + END IF; + END IF; + + -- AMB- of SSCA-medewerker: alleen in tekstveld zetten + -- (Zowel bij create als update hele string weer opbouwen) + -- Voor OF-ruimtes (res_disc 1485) behandelen we iedereen als AMB-/SSCA-medewerker + -- AKZA#38968: badgenummer is voortaan vereist om genodigde te zijn + -- AKZA#40274: bepaling van bezoekers/deelnemers voor ruimtes uit disc 1485 op dezelfde wijze als andere ruimtes / op verzoek van André weer ongedaan gemaakt + -- KFSG#57950: Bovenstaande nog even laten staan. Voor Schiphol geldt dat medewerkers (@schiphol in e-mail adres) in Genodigden-veld komen. + -- TODO: Of Genodigden-veld helemaal weg??? + --IF (rec.alg_locatie_key IS NOT NULL AND rec.badgenr IS NOT NULL) + IF (rec.alg_locatie_key IS NOT NULL AND INSTR (UPPER (rec.att_mail), '@SCHIPHOL.NL') > 0) + THEN + v_genodigden := v_genodigden || rec.att_name || CHR(13); + -- Overige AN-medewerkers en gasten aanmelden als bezoeker (of registratie bijwerken) + ELSE + -- Er zijn niet-AMB-/SSCA-medewerker attendees, zorgen dat er een afspraak is + IF (v_afspraak_key IS NULL) + THEN + v_afspraak_key := demo.getAfspraak(p_rsv_ruimte_key, 1); + + -- Moet de afspraak verplaatst worden in de tijd? + SELECT bez_afspraak_datum, + bez_afspraak_eind, + rr.res_rsv_ruimte_van, + rr.res_rsv_ruimte_tot + INTO v_datum_old, v_eind_old, v_datum_new, v_eind_new + FROM res_rsv_ruimte rr, + bez_afspraak a + WHERE rr.res_rsv_ruimte_key = p_rsv_ruimte_key + AND a.res_rsv_ruimte_key = rr.res_rsv_ruimte_key; + + IF (v_datum_old != v_datum_new OR v_eind_old != v_eind_new) + THEN + UPDATE bez_afspraak + SET bez_afspraak_datum = v_datum_new, + bez_afspraak_eind = v_eind_new + WHERE bez_afspraak_key = v_afspraak_key; + IF (v_debug) THEN + fac.imp_writelog (p_import_key, 'D', + p_rsv_ruimte_key||', AFSPRAAK '||v_afspraak_key, + 'Tijden aangepast van ' + ||TO_CHAR(v_datum_old,'HH24:MI')||'-' + ||TO_CHAR(v_eind_old, 'HH24:MI')||' --> ' + ||TO_CHAR(v_datum_new,'HH24:MI')||'-' + ||TO_CHAR(v_eind_new, 'HH24:MI') ); + END IF; + END IF; + + IF (v_debug) THEN + fac.imp_writelog (p_import_key, 'D', + p_rsv_ruimte_key, 'AFSPRAAK '||v_afspraak_key); + END IF; + END IF; + demo.upsertBezoeker(p_import_key, v_afspraak_key, rec.bez_bezoekers_key, rec.att_mail, rec.att_name, rec.prs_perslid_key, rec.prs_afdeling_naam ); + END IF; + + -- Opruiming: afspraken zonder bezoekers (kan gebeuren als er alleen nog interne deelnemers zijn, + -- of de meeting is verplaatst naar een OF-ruimte) + DELETE bez_afspraak a + WHERE res_rsv_ruimte_key = p_rsv_ruimte_key + AND NOT EXISTS (SELECT 1 FROM bez_bezoekers WHERE bez_afspraak_key = a.bez_afspraak_key); + END LOOP; + + IF (v_debug AND v_discipline_key IS NOT NULL) THEN + fac.imp_writelog (p_import_key, 'D', + p_rsv_ruimte_key, 'Ruimte-catalogus = '||v_discipline_key); + fac.imp_writelog (p_import_key, 'D', + p_rsv_ruimte_key, SUBSTR('GENODIGDEN: '||CHR(13) ||v_genodigden, 1, 1000) ); + END IF; + demo.upsertkenmerk_res(c_km_key_genodigden, p_rsv_ruimte_key, v_genodigden ); + END IF; + + END; + + -- Haalt bestaande afspraak bij rsv_ruimte op, of maakt een nieuwe + FUNCTION getAfspraak (p_rsv_ruimte_key IN NUMBER, + p_createnew IN NUMBER) + RETURN NUMBER + IS + v_count NUMBER; + r_afspraak_key NUMBER; + BEGIN + r_afspraak_key := NULL; + + --Bestaat er al een afspraak? + SELECT COUNT(*) + INTO v_count + FROM bez_afspraak + WHERE res_rsv_ruimte_key IS NOT NULL + AND res_rsv_ruimte_key = p_rsv_ruimte_key; + + -- Nee, maak eerst een nieuwe, mits createnew = 1 + IF (v_count = 0 AND p_createnew = 1) + THEN + INSERT INTO bez_afspraak ( + prs_perslid_key, + bez_afspraak_datum, + bez_actie_key, + bez_afspraak_ruimte, + bez_afspraak_opmerking, + bez_afspraak_eind, + alg_locatie_key, + alg_onrgoed_keys, + bez_afspraak_host_key, + bez_afspraak_contact_key, + res_rsv_ruimte_key) + SELECT rr.res_rsv_ruimte_contact_key, + rr.res_rsv_ruimte_van, + NULL, + SUBSTR (r.res_ruimte_nr, 1, 30), + SUBSTR ('Overgenomen uit Exchange', 1, 320), + rr.res_rsv_ruimte_tot, + g.alg_locatie_key, + MIN(rar.alg_ruimte_key), + rr.res_rsv_ruimte_host_key, + rr.res_rsv_ruimte_contact_key, + rr.res_rsv_ruimte_key + FROM res_rsv_ruimte rr, + res_ruimte_opstelling ro, + res_ruimte r, + res_alg_ruimte rar, + alg_v_aanwezigruimte ar, + alg_verdieping v, + alg_gebouw g + WHERE rr.res_rsv_ruimte_key = p_rsv_ruimte_key + AND ro.res_ruimte_opstel_key = rr.res_ruimte_opstel_key + AND r.res_ruimte_key = ro.res_ruimte_key + AND rar.res_ruimte_key = r.res_ruimte_key + AND rar.res_alg_ruimte_verwijder IS NULL + AND ar.alg_ruimte_key = rar.alg_ruimte_key + AND v.alg_verdieping_key = ar.alg_verdieping_key + AND g.alg_gebouw_key = v.alg_gebouw_key + GROUP BY rr.res_rsv_ruimte_contact_key, rr.res_rsv_ruimte_van, r.res_ruimte_nr, + rr.res_rsv_ruimte_tot, g.alg_locatie_key, rr.res_rsv_ruimte_host_key, + rr.res_rsv_ruimte_contact_key, rr.res_rsv_ruimte_key; + + -- TODO: +-- BEGIN fac.trackaction('BEZMUT', -1, 3, NULL, NULL); END; + END IF; + + -- Haal bestaande / nieuwe key op (RETURNING kan niet met een INSERT .. SELECT) + -- (alleen als we er net een hebben aangemaakt of er al een was + IF NOT (v_count = 0 AND p_createnew = 0) + THEN + SELECT bez_afspraak_key + INTO r_afspraak_key + FROM bez_afspraak + WHERE res_rsv_ruimte_key IS NOT NULL + AND res_rsv_ruimte_key = p_rsv_ruimte_key; + END IF; + + RETURN r_afspraak_key; + + END; + + PROCEDURE upsertBezoeker (p_import_key IN NUMBER, + p_afspraak_key IN NUMBER, + p_bezoekers_key IN NUMBER, + p_att_mail IN VARCHAR2, + p_att_name IN VARCHAR2, + p_perslid_key IN NUMBER, + p_afdeling_naam IN VARCHAR2) + IS + v_debug BOOLEAN := TRUE; + v_bez_flags NUMBER (10); + v_bezoekers_key NUMBER (10); + v_count NUMBER; + BEGIN + v_bez_flags := 0; + + -- AN-medewerkers op overige locaties: + -- aanmelden als bezoeker (met perslid_key, als bekend), zonder (mogelijkheid tot) parkeerplaats + -- flags (AKZA#34209) + -- 2: andere locatie + -- 16: geen parkeerplaats mogelijk + IF (UPPER(p_att_mail) LIKE '%@SCHIPHOL.NL') + THEN + IF (v_debug) THEN + fac.imp_writelog (p_import_key, 'D', + p_afspraak_key, 'SG-mw '||p_att_name|| ' ('||COALESCE(TO_CHAR(p_perslid_key), p_att_mail)||')'); + END IF; + v_bez_flags := 2 + 16; + + -- Gasten: aanmelden als gewone bezoeker (zonder perslid_key), met parkeerplaats + -- flags = 0 + ELSE + IF (v_debug) THEN + fac.imp_writelog (p_import_key, 'D', + p_afspraak_key, 'Gast '||p_att_name|| ' ('||p_att_mail||')'); + END IF; + v_bez_flags := 0; + END IF; + + -- Bestaat bezoeker al bij deelreservering? Dan alleen basisgegevens bijwerken + IF (p_bezoekers_key IS NOT NULL) + THEN + -- Bijwerken + UPDATE bez_bezoekers + SET prs_perslid_key = p_perslid_key, + bez_afspraak_naam = SUBSTR(p_att_name, 1, 30), + bez_afspraak_bedrijf = SUBSTR(p_afdeling_naam, 1, 60), + bez_bezoekers_flags = v_bez_flags + WHERE bez_bezoekers_key = p_bezoekers_key; + + -- Als deze bezoeker een parkeerplaats heeft, probeer dan een nieuwe te claimen + -- alg_gebouw "SHG" 48 + IF ( bez.hasparking(p_bezoekers_key) = 1) + THEN + DELETE FROM res_rsv_deel + WHERE bez_bezoekers_key = p_bezoekers_key; + IF ( BITAND(v_bez_flags, 16) = 0) + THEN + bez.claim_parking(p_bezoekers_key, 48); + END IF; + -- TODO: track? + END IF; + + -- Nieuwe bezoeker: toevoegen, plus parkeerplaats en mailadres + ELSE + INSERT INTO bez_bezoekers ( + bez_afspraak_key, + prs_perslid_key, + bez_afspraak_naam, + bez_afspraak_bedrijf, + bez_bezoekers_flags) + VALUES ( + p_afspraak_key, + p_perslid_key, + SUBSTR(p_att_name, 1, 30), + SUBSTR(p_afdeling_naam, 1, 60), + v_bez_flags) + RETURNING bez_bezoekers_key INTO v_bezoekers_key; + + -- Voor nieuwe gasten een parkeerplek claimen + -- alg_gebouw "SHG" 48 + IF ( BITAND(v_bez_flags, 16) = 0) + THEN + bez.claim_parking(v_bezoekers_key, 48); + END IF; + + -- Mailadres opslaan + -- bez_kenmerk E-mail 1120 + demo.upsertkenmerk_bez(1120, v_bezoekers_key, p_att_mail); + END IF; + + -- TODO: tracking; liefst geen aparte regel per bezoeker +-- fac.trackaction('BEZMUT', p_afspraak_key, NULL, NULL, 'Bezoeker '||p_att_name||' toegevoegd/gewijzigd'); + END; + + PROCEDURE upsertkenmerk_bez (p_kenmerk_key IN NUMBER, + p_bez_key IN NUMBER, + p_waarde IN VARCHAR2) + IS + v_count NUMBER; + BEGIN + SELECT COUNT ( * ) + INTO v_count + FROM bez_kenmerkwaarde + WHERE bez_bezoekers_key = p_bez_key + AND bez_kenmerk_key = p_kenmerk_key + AND bez_kenmerkwaarde_verwijder IS NULL; + + IF v_count = 1 + THEN + IF p_waarde IS NULL + THEN + DELETE bez_kenmerkwaarde + WHERE bez_bezoekers_key = p_bez_key + AND bez_kenmerk_key = p_kenmerk_key + AND bez_kenmerkwaarde_verwijder IS NULL; + ELSE + UPDATE bez_kenmerkwaarde + SET bez_kenmerkwaarde_waarde = p_waarde + WHERE bez_bezoekers_key = p_bez_key + AND bez_kenmerk_key = p_kenmerk_key + AND bez_kenmerkwaarde_verwijder IS NULL; + END IF; + ELSE + IF p_kenmerk_key IS NOT NULL AND p_waarde IS NOT NULL + THEN + INSERT INTO bez_kenmerkwaarde (bez_kenmerk_key, + bez_bezoekers_key, + bez_kenmerkwaarde_waarde) + VALUES (p_kenmerk_key, + p_bez_key, + p_waarde); + END IF; + END IF; + END; + + PROCEDURE upsertkenmerk_res(p_kenmerk_key IN NUMBER, + p_rsv_ruimte_key IN NUMBER, + p_waarde IN VARCHAR2) + IS + v_count NUMBER; + BEGIN + SELECT COUNT ( * ) + INTO v_count + FROM res_kenmerkwaarde + WHERE res_rsv_ruimte_key = p_rsv_ruimte_key + AND res_kenmerk_key = p_kenmerk_key + AND res_kenmerkwaarde_verwijder IS NULL; + + IF v_count = 1 + THEN + IF p_waarde IS NULL + THEN + DELETE res_kenmerkwaarde + WHERE res_rsv_ruimte_key = p_rsv_ruimte_key + AND res_kenmerk_key = p_kenmerk_key + AND res_kenmerkwaarde_verwijder IS NULL; + ELSE + UPDATE res_kenmerkwaarde + SET res_kenmerkreservering_waarde = p_waarde + WHERE res_rsv_ruimte_key = p_rsv_ruimte_key + AND res_kenmerk_key = p_kenmerk_key + AND res_kenmerkwaarde_verwijder IS NULL; + END IF; + ELSE + IF p_kenmerk_key IS NOT NULL AND p_waarde IS NOT NULL + THEN + INSERT INTO res_kenmerkwaarde (res_kenmerk_key, + res_rsv_ruimte_key, + res_kenmerkreservering_waarde) + VALUES (p_kenmerk_key, + p_rsv_ruimte_key, + p_waarde); + END IF; + END IF; + END; + + -- Zoek de default (of anders oudste) opstelling bij de ruimte obv room-id + FUNCTION getOpstelling(p_room_id IN VARCHAR2) + RETURN NUMBER + IS + v_ruimte_opstel_key NUMBER (10); + BEGIN + v_ruimte_opstel_key := NULL; + + SELECT COALESCE(ro1.res_ruimte_opstel_key, ro2.res_ruimte_opstel_key) res_ruimte_opstel_key + INTO v_ruimte_opstel_key + FROM res_ruimte r, + (SELECT * FROM res_ruimte_opstelling + WHERE res_ruimte_opstel_verwijder IS NULL + AND res_ruimte_opstel_default = 1) ro1, + (SELECT * FROM res_ruimte_opstelling + WHERE res_ruimte_opstel_verwijder IS NULL) ro2 + WHERE r.res_ruimte_extern_id = p_room_id + AND r.res_ruimte_verwijder IS NULL + AND COALESCE(r.res_ruimte_vervaldatum, SYSDATE+1) > SYSDATE + AND ro1.res_ruimte_key(+) = r.res_ruimte_key + AND ro2.res_ruimte_key = r.res_ruimte_key + AND ro2.res_ruimte_opstel_key = (SELECT MIN(res_ruimte_opstel_key) + FROM res_ruimte_opstelling + WHERE res_ruimte_opstel_verwijder IS NULL + AND res_ruimte_key = r.res_ruimte_key); + + RETURN v_ruimte_opstel_key; + EXCEPTION + WHEN NO_DATA_FOUND + THEN + RETURN NULL; + END; + + -- Aangeroepen vanuit bez_postsave hook. Controleert of deze bezoeker wel een parkeerplaats + -- mag hebben (obv bez_bezoekers_flags) en verwijdert zonodig + PROCEDURE checkParking(p_bezoekers_key IN NUMBER) + IS + v_bez_flags bez_bezoekers.bez_bezoekers_flags%TYPE; + v_rsv_deel_key NUMBER (10); + BEGIN + -- Haal bezoeker-flags op, en een eventuele + SELECT b.bez_bezoekers_flags, rd.res_rsv_deel_key + INTO v_bez_flags, v_rsv_deel_key + FROM bez_bezoekers b, + (SELECT * FROM res_rsv_deel + WHERE res_rsv_deel_verwijder IS NULL) rd + WHERE b.bez_bezoekers_key = p_bezoekers_key + AND rd.bez_bezoekers_key(+) = b.bez_bezoekers_key; + + -- Bezoeker mag geen parkeerplaats, maar heeft er wel een --> weg ermee! + -- bits: +1 Medewerker uit eigen locatie, is waarschijnlijk al binnen + -- +2 Medewerker van andere locatie (heeft doorgaans bedrijfspasje) + -- +4 Deelnemer die niet fysiek komt (Skype/Video conference) + -- +8 Bezoekers meldt zich niet aan de balie (waarschijnlijk bij een +1/2/4) + -- +16 Geen parkeerplaats toe (te) kennen of af te pakken (vaak icm. +1/2/4) + IF ( BITAND(v_bez_flags, 31) != 0 AND v_rsv_deel_key IS NOT NULL) + THEN + DELETE res_rsv_deel + WHERE res_rsv_deel_key = v_rsv_deel_key; + END IF; + + EXCEPTION + WHEN NO_DATA_FOUND + THEN + NULL; + END; + + -- Welbeschouwd kunnen door de Exchange-constraints ruimte reserveringen nooit overlappen + -- Als er in FACILITOR toch een overlap is ontstaan is dat eigenlijk een gebrek van + -- de synchronisatie procedure + -- Daarom veronderstellen wij dat toch degene die dirty was geworden de waarheid is + -- en de 'andere' dirty had moeten worden of sterker nog: we verwijderen de andere + PROCEDURE set_ruimtes_clean(p_import_key IN NUMBER) + IS + dirtlevel res_rsv_ruimte.res_rsv_ruimte_dirtlevel%TYPE; + v_errorhint VARCHAR2 (1000); + + CURSOR c_prsv_ruimte_new + IS + SELECT rr.res_rsv_ruimte_key, + r.res_ruimte_key, + res_rsv_ruimte_van, + res_reservering_key, + res_rsv_ruimte_volgnr + FROM res_ruimte r, res_ruimte_opstelling ro, res_rsv_ruimte rr + WHERE ro.res_ruimte_opstel_key = rr.res_ruimte_opstel_key + AND r.res_ruimte_key = ro.res_ruimte_key + AND res_rsv_ruimte_dirtlevel = 512 -- alleen ruimteoverlap corrigeren we + AND res_rsv_ruimte_verwijder IS NULL + AND res_ruimte_extern_id IS NOT NULL + AND res_rsv_ruimte_van > TRUNC (SYSDATE) + ORDER BY res_rsv_ruimte_key DESC + FOR UPDATE OF res_rsv_ruimte_dirtlevel; + BEGIN + FOR prsv_ruimte_new IN c_prsv_ruimte_new + LOOP + -- Wij in ieder geval niet meer dirty + v_errorhint := 'Cleanup reservering ' + || TO_CHAR(prsv_ruimte_new.res_reservering_key) || '/' || prsv_ruimte_new.res_rsv_ruimte_volgnr + || ' (' || TO_CHAR(prsv_ruimte_new.res_rsv_ruimte_key) || ')'; + + fac.imp_writelog (p_import_key, 'I', v_errorhint, ''); + + UPDATE res_rsv_ruimte + SET res_rsv_ruimte_dirtlevel = 0 + WHERE CURRENT OF c_prsv_ruimte_new; -- geen tracking + + -- Controleer alle andere reserveringen op die dag in die zaal om te weten welke + -- ons dirty had gemaakt + FOR prsv_ruimte_old + IN (SELECT rr.res_rsv_ruimte_key, + res_rsv_ruimte_van, + res_rsv_ruimte_tot, + res_reservering_key, + res_rsv_ruimte_volgnr + FROM res_ruimte r, res_ruimte_opstelling ro, res_rsv_ruimte rr + WHERE r.res_ruimte_key = prsv_ruimte_new.res_ruimte_key + AND rr.res_rsv_ruimte_key <> prsv_ruimte_new.res_rsv_ruimte_key + AND ro.res_ruimte_opstel_key = rr.res_ruimte_opstel_key + AND r.res_ruimte_key = ro.res_ruimte_key + AND BITAND(res_rsv_ruimte_dirtlevel, 512) = 0 + AND res_rsv_ruimte_verwijder IS NULL + AND res_rsv_ruimte_van BETWEEN TRUNC(prsv_ruimte_new.res_rsv_ruimte_van) + AND TRUNC(prsv_ruimte_new.res_rsv_ruimte_van) + 1) + LOOP + -- Degene die met ons overlapte zal dirty worden nu wij vrij zijn + v_errorhint := 'Checking reservering ' + || TO_CHAR(prsv_ruimte_old.res_reservering_key) || '/' || prsv_ruimte_old.res_rsv_ruimte_volgnr + || ' (' || TO_CHAR(prsv_ruimte_old.res_rsv_ruimte_key) || ')'; + + fac.imp_writelog (p_import_key, 'D', v_errorhint, ''); + res.set_ruimte_dirty (prsv_ruimte_old.res_rsv_ruimte_key); -- deze houdt rekening met schoonmaaak + + SELECT res_rsv_ruimte_dirtlevel + INTO dirtlevel + FROM res_rsv_ruimte + WHERE res_rsv_ruimte_key = prsv_ruimte_old.res_rsv_ruimte_key; + + IF BITAND(dirtlevel, 512) <> 0 + THEN + v_errorhint := 'Remove dirty reservering ' + || TO_CHAR(prsv_ruimte_old.res_reservering_key) || '/' || prsv_ruimte_old.res_rsv_ruimte_volgnr + || ' (' || TO_CHAR(prsv_ruimte_old.res_rsv_ruimte_key); + fac.imp_writelog (p_import_key, 'I', v_errorhint, ''); + + UPDATE res_rsv_ruimte + SET res_status_fo_key = 1, -- nooit doorbelasten + res_rsv_ruimte_verwijder = SYSDATE + WHERE res_rsv_ruimte_key = prsv_ruimte_old.res_rsv_ruimte_key; + + fac.trackaction ('RESDEL', prsv_ruimte_old.res_rsv_ruimte_key, NULL, SYSDATE, NULL); + + res.set_ruimtes_clean (prsv_ruimte_old.res_rsv_ruimte_van); -- onwaarschijnlijk + res.follow_artikel (prsv_ruimte_old.res_rsv_ruimte_key, + prsv_ruimte_old.res_rsv_ruimte_van, + prsv_ruimte_old.res_rsv_ruimte_tot); + res.follow_deel (prsv_ruimte_old.res_rsv_ruimte_key, + prsv_ruimte_old.res_rsv_ruimte_van, + prsv_ruimte_old.res_rsv_ruimte_tot); + + v_errorhint := 'res_reservering verwijderen'; + + UPDATE res_reservering + SET res_reservering_verwijder = SYSDATE + WHERE res_reservering_key = prsv_ruimte_old.res_reservering_key + AND NOT EXISTS + (SELECT * + FROM res_v_aanwezigrsv_ruimte + WHERE res_reservering_key = prsv_ruimte_old.res_reservering_key); + END IF; + END LOOP; + END LOOP; + END; + + + + + -- Bepaal aantal dagen in begin- of eindperiode waarvoor huur betaald moet worden -- Periode moet binnen dezelfde kalendermaand liggen. -- Als p_periode_tot leeg is, gaan we uit van het einde van de maand @@ -4033,6 +4801,1255 @@ AS END; / + + + +-------------------------------------------------------------------------------------------------- +------------------------------- IMPORT ----------------------------------------------------------- +-------------------------------------------------------------------------------------------------- + +-- Met behulp van demo_imp_exchange.gelukt kunnen importregels bewaard worden, zodat mutaties +-- aan appointments die gefaald zijn, alsnog kunnen worden doorgevoerd. Betekenis waarden 'gelukt': +-- NULL = niet correct verwerkt in vorige import --> nogmaals proberen +-- 1 = succesvol verwerkt in vorige import --> importregel verwijderen +-- 2 = er is in een latere import een nieuwere status van dezelfde appointment ingelezen, +-- dus deze importregel is outdated --> regel verwijderen +CREATE OR REPLACE PROCEDURE demo_import_exchange ( + p_import_key IN NUMBER +) +IS + c_fielddelimitor VARCHAR2 (1) := ';'; + c_max_errors NUMBER := 100; + v_newline VARCHAR2 (1000); -- Input line + v_aanduiding VARCHAR2 (200); + v_errorhint VARCHAR2 (1000); + v_errormsg VARCHAR2 (1000); + oracle_err_num NUMBER; + oracle_err_mes VARCHAR2 (200); + header_is_valid NUMBER; + v_ongeldig NUMBER (1); + v_count_tot NUMBER (10); + v_count_error NUMBER (10); + v_count_import NUMBER (10); + v_count NUMBER; + v_import_filenaam fac_import.fac_import_filenaam%TYPE; + v_ruimte_id res_ruimte.res_ruimte_extern_id%TYPE; + + -- De importvelden: + v_room_id VARCHAR2 (200); + v_subject VARCHAR2 (200); + v_starttime VARCHAR2 (100); + v_endtime VARCHAR2 (100); + v_organizer VARCHAR2 (200); + v_att_mail VARCHAR2 (200); + v_att_name VARCHAR2 (200); + v_modifier VARCHAR2 (100); + v_appt_id VARCHAR2 (500); + v_recur_id VARCHAR2 (500); + v_seq_nr VARCHAR2 (100); + d_starttime DATE; + d_endtime DATE; + n_seq_nr NUMBER(10); + + CURSOR c + IS + SELECT * + FROM fac_imp_file + WHERE fac_import_key = p_import_key + ORDER BY fac_imp_file_index; +BEGIN + -- AKZA#36457: de ID van de ruimte is niet meer uit de inhoud van de XML te halen. + -- Dan maar de bestandsnaam gebruiken (refkey is niet handig, want dan moeten we voor + -- elke room de import draaien). + SELECT r.res_ruimte_extern_id, i.fac_import_filenaam + INTO v_ruimte_id, v_import_filenaam + FROM res_ruimte r, fac_import i + WHERE i.fac_import_key = p_import_key + AND r.res_ruimte_verwijder IS NULL + AND r.res_ruimte_extern_id IS NOT NULL + AND UPPER(i.fac_import_filenaam) LIKE 'SYNC_'||UPPER(r.res_ruimte_extern_id)||'%'; + + fac.imp_writelog (p_import_key, 'S', + 'Start inlezen importbestand in importtabel', + v_import_filenaam ); + + -- We willen mislukte regels uit eerdere imports bewaren, zodat we die nog eens kunnen proberen. + -- Alle correct verwerkte importregels krijgen een vlag, dus die gooien we weg. + DELETE FROM demo_imp_exchange + WHERE gelukt IS NOT NULL; + + -- We gaan uit van een geldig bestand, mogelijk verandert dat onderweg + header_is_valid := 0; + v_ongeldig := 0; + v_count_tot := 0; + v_count_error := 0; + v_count_import := 0; + + FOR rec IN c + LOOP + BEGIN + v_newline := rec.fac_imp_file_line; + v_aanduiding := ''; + d_starttime := NULL; + d_endtime := NULL; + v_errorhint := 'Fout bij opvragen te importeren rij'; + + -- Lees alle veldwaarden + --AKZA#36457: room ID wordt voortaan opgehaald uit de bestandsnaam van de import + v_room_id := v_ruimte_id; + fac.imp_getfield_nr (v_newline, c_fielddelimitor, 1, v_subject); + fac.imp_getfield_nr (v_newline, c_fielddelimitor, 2, v_starttime); + fac.imp_getfield_nr (v_newline, c_fielddelimitor, 3, v_endtime); + fac.imp_getfield_nr (v_newline, c_fielddelimitor, 4, v_organizer); + fac.imp_getfield_nr (v_newline, c_fielddelimitor, 5, v_att_mail); + fac.imp_getfield_nr (v_newline, c_fielddelimitor, 6, v_att_name); + fac.imp_getfield_nr (v_newline, c_fielddelimitor, 7, v_modifier); + fac.imp_getfield_nr (v_newline, c_fielddelimitor, 8, v_appt_id); + fac.imp_getfield_nr (v_newline, c_fielddelimitor, 9, v_recur_id); + fac.imp_getfield_nr (v_newline, c_fielddelimitor, 10, v_seq_nr); + + v_aanduiding := '[' || v_room_id || '|' || v_starttime || '|' || v_att_mail || '] '; + + -- Ik controleer of ik een geldige header heb, dat is: in de juiste kolommen + -- de juiste kolomkop. Ik controleer daarbij ALLE kolommen! + -- Ik negeer alles totdat ik een geldige header ben gepasseerd. + -- NB: doordat deze import een stylesheet gebruikt, zullen deze kolommen altijd kloppen, + -- ook al wordt een verkeerd bestand ingelezen (mits de stylesheet klopt) + IF (header_is_valid = 0) + THEN + IF UPPER(v_subject) = 'SUBJECT' + AND UPPER(v_starttime) = 'STARTTIME' + THEN + header_is_valid := 1; + END IF; + ELSE + -- Bij volgende importbestanden headerregels overslaan + IF UPPER(v_subject) = 'SUBJECT' + AND UPPER(v_starttime) = 'STARTTIME' + THEN + CONTINUE; + END IF; + v_count_tot := v_count_tot + 1; + + -- Controleer tijden + v_errorhint := 'Ongeldige starttijd'; + v_starttime := TRIM(v_starttime); + + IF ( fac.safe_to_date(v_starttime, 'YYYY-MM-DD"T"HH24:MI:SS"Z"') IS NOT NULL) + THEN + d_starttime := CAST ( + (FROM_TZ ( + CAST (fac.safe_to_date(v_starttime, 'YYYY-MM-DD"T"HH24:MI:SS"Z"') + AS TIMESTAMP), + '+00:00') AT TIME ZONE 'Europe/Amsterdam') + AS DATE); + ELSE + v_ongeldig := 1; + v_count_error := v_count_error + 1; + fac.imp_writelog (p_import_key, 'W', + v_aanduiding || 'Starttijd ontbreekt', + '' ); + END IF; + + v_errorhint := 'Ongeldige eindtijd'; + v_endtime := TRIM(v_endtime); + + IF ( fac.safe_to_date(v_endtime, 'YYYY-MM-DD"T"HH24:MI:SS"Z"') IS NOT NULL) + THEN + d_endtime := CAST ( + (FROM_TZ ( + CAST (fac.safe_to_date(v_endtime, 'YYYY-MM-DD"T"HH24:MI:SS"Z"') + AS TIMESTAMP), + '+00:00') AT TIME ZONE 'Europe/Amsterdam') + AS DATE); + ELSE + v_ongeldig := 1; + v_count_error := v_count_error + 1; + fac.imp_writelog (p_import_key, 'W', + v_aanduiding || 'Eindtijd ontbreekt', + '' ); + END IF; + + v_errorhint := 'Opschonen naam bezoeker'; + v_att_name := TRIM(BOTH '''' FROM v_att_name); + + v_errorhint := 'Ongeldig sequence nr'; + v_seq_nr := TRIM(v_seq_nr); + + IF ( fac.safe_to_number(v_seq_nr) IS NOT NULL) + THEN + n_seq_nr := fac.safe_to_number(v_seq_nr); + ELSE + v_ongeldig := 1; + v_count_error := v_count_error + 1; + fac.imp_writelog (p_import_key, 'W', + v_aanduiding || 'Sequence nr ontbreekt', + '' ); + END IF; + + -- Insert geformatteerde import record, + -- mits het een toekomstige appointment betreft + IF (v_ongeldig = 0 AND d_starttime > SYSDATE) + THEN + BEGIN + v_errorhint := 'Fout bij toevoegen regel aan importtabel'; + + INSERT INTO demo_imp_exchange + (room_id, + subject, + starttime, + endtime, + organizer, + att_mail, + att_name, + modifier, + appt_id, + recur_id, + seq_nr, + fac_import_key) + VALUES + (v_room_id, + v_subject, + d_starttime, + d_endtime, + v_organizer, + v_att_mail, + v_att_name, + SUBSTR(v_modifier, 1, 1), + v_appt_id, + v_recur_id, + n_seq_nr, + p_import_key); + + v_count_import := v_count_import + 1; + + EXCEPTION + WHEN OTHERS + THEN + oracle_err_num := SQLCODE; + oracle_err_mes := SUBSTR (SQLERRM, 1, 100); + v_errormsg := + v_errorhint + || ': ORACLE (error ' + || oracle_err_num + || '/' + || oracle_err_mes + || ')'; + v_ongeldig := 1; + fac.imp_writelog + (p_import_key, + 'E', + v_aanduiding || v_errormsg, + 'Ingelezen regel kan niet worden weggeschreven!' + ); + COMMIT; + END; + END IF; + + END IF; + END; + END LOOP; + + IF (header_is_valid = 0) + THEN + fac.imp_writelog (p_import_key, + 'E', + 'Ongeldig importbestand! Geen header of header niet volgens specificatie.', + 'Heeft u wel het juiste bestand ingelezen?' + ); + ELSIF (v_ongeldig = 1) + THEN + fac.imp_writelog (p_import_key, + 'E', + 'Ongeldig importbestand! Bestand bevat een of meer ongeldige regels.', + '' + ); + ELSE + fac.imp_writelog (p_import_key, + 'S', + 'Importbestand succesvol ingelezen: ' + || TO_CHAR (v_count_import) || ' regels (deelnemers).', + '' + ); + END IF; + + COMMIT; + + -- demo_import_exchange() wordt voor elk importbestand aangeroepen. Dat gebeurt steeds met dezelfde + -- fac_import_key, dus er kan achteraf niet bepaald worden welke importregels bij welk bestand (en + -- dus welke ruimte horen. Daarom fac_imp_file handmatig legen, zodat we bij het volgende bestand + -- met een schone lei beginnen. + DELETE FROM fac_imp_file + WHERE fac_import_key = p_import_key; + + COMMIT; + +EXCEPTION + WHEN OTHERS + THEN + oracle_err_num := SQLCODE; + oracle_err_mes := SUBSTR (SQLERRM, 1, 100); + v_errormsg := + 'OTHERS (error ' || oracle_err_num || '/' || oracle_err_mes || ')'; + + fac.imp_writelog (p_import_key, + 'E', + v_aanduiding || v_errormsg, + v_errorhint + ); + + -- AKZA#38120: ook als er iets mis gaat bij inlezen (bijvoorbeeld de extern_id bestaat niet, of + -- komt vaker voor) de importregels weggooien, anders worden ze bij de volgende ruimte ingelezen. + -- Liever niets inlezen (totdat de situatie verholpen is), dan fout inlezen. + DELETE FROM fac_imp_file + WHERE fac_import_key = p_import_key; + + COMMIT; +END demo_import_exchange; +/ + + +CREATE OR REPLACE PROCEDURE demo_update_exchange ( + p_import_key IN NUMBER +) +IS + v_aanduiding VARCHAR2 (200); + v_errorhint VARCHAR2 (1000); + v_errormsg VARCHAR2 (1000); + oracle_err_num NUMBER; + oracle_err_mes VARCHAR2 (200); + v_count_tot NUMBER (10); + v_count_error NUMBER (10); + v_count NUMBER (10); + v_ruimte_extern_id res_ruimte.res_ruimte_extern_id%TYPE; + v_count_wanted NUMBER (10); + v_count_all_booked NUMBER (10); + v_count_all_needed NUMBER (10); + v_ongeldig NUMBER (1); + v_debug BOOLEAN := TRUE; + + c_activiteit_key NUMBER (10) := 1; -- Vergadering + v_reservering_key NUMBER (10); + v_rsv_ruimte_volgnr res_rsv_ruimte.res_rsv_ruimte_volgnr%TYPE; + v_ruimte_opstel_key NUMBER (10); + v_rsv_ruimte_key NUMBER (10); + v_perslid_key NUMBER (10); + v_kostenplaats_key NUMBER (10); + v_status_fo_key NUMBER (10); + v_discipline_key NUMBER (10); + v_code VARCHAR2(7); + + -- ANNULEREN + -- Eerst alle toekomstige reserveringen waar geen appointments meer bij zijn annuleren, zodat + -- ruimte ontstaat voor nieuwe/omgeboekte reserveringen. + -- Triggers voor het annuleren van een deelreservering: + -- - DELETE-modifier in synchro; appointment is verwijderd + -- - UPDATE-modifier in synchro, met bekend appointment-ID, maar zonder resource: de appointment + -- bestaat nog, maar is niet meer in een bekende zaal (TODO: krijgen we die dan als UPD, of als DEL?) + -- - UPDATE-modifier in synchro, met bekend appointment-ID, maar voorheen zonder recurrence-ID (= single) + -- en nu met recurrence-ID (= occurence). Die single verwijderen, daarna de occurences toevoegen. + -- NB: checken of in deze synchro een appointment niet zowel toegevoegd/bijgewerkt als verwijderd is; + -- dan hoeven we 'm natuurlijk niet meer toe te voegen / bij te werken. + -- (TODO: weet niet of dat uberhaupt voorkomt met EWS) + -- TODO: notificeren + CURSOR c_del + IS + SELECT 'Cancelled' reden, + i.*, + rr.* + FROM (SELECT DISTINCT room_id, + subject, + starttime, + endtime, + organizer, + modifier, + appt_id, + recur_id + FROM demo_imp_exchange + WHERE modifier = 'D' + AND starttime > SYSDATE + AND gelukt IS NULL) i, + res_rsv_ruimte rr + WHERE rr.res_rsv_ruimte_externnr IS NOT NULL + AND rr.res_rsv_ruimte_externnr LIKE i.appt_id||'|'||i.recur_id||'|%' + AND rr.res_rsv_ruimte_verwijder IS NULL + UNION ALL + SELECT 'Unknown room' reden, + i.*, + rr.* + FROM (SELECT DISTINCT room_id, + subject, + starttime, + endtime, + organizer, + modifier, + appt_id, + recur_id + FROM demo_imp_exchange + WHERE modifier = 'U' + AND starttime > SYSDATE + AND gelukt IS NULL) i, + res_rsv_ruimte rr + WHERE rr.res_rsv_ruimte_externnr LIKE i.appt_id||'|'||i.recur_id||'|%' + AND rr.res_rsv_ruimte_verwijder IS NULL + AND NOT EXISTS (SELECT 1 + FROM res_ruimte + WHERE res_ruimte_extern_id = i.room_id + AND res_ruimte_verwijder IS NULL) + UNION ALL + -- AKZA#35459: appointments die eerst single waren en nu recurring (eerst geen + -- recur_id, nu wel). Daar kan vanalles mee gebeurd zijn (andere ruimte, ander tijdstip, + -- meerdere ruimtes). Dan maar verwijderen en opnieuw aanmaken... + -- (recur_id en tijden niet ophalen, anders wordt de 'oude' single voor elke recurrence verwijderd) + SELECT 'Made recurring' reden, + i.*, + rr.* + FROM (SELECT DISTINCT room_id, + subject, + NULL starttime, + NULL endtime, + organizer, + modifier, + appt_id, + NULL recur_id + FROM demo_imp_exchange + WHERE modifier = 'U' + AND starttime > SYSDATE + AND recur_id IS NOT NULL + AND gelukt IS NULL) i, + res_rsv_ruimte rr + WHERE rr.res_rsv_ruimte_externnr LIKE i.appt_id||'||%' + AND rr.res_rsv_ruimte_verwijder IS NULL; + + -- TODO: Voor later: res_cat_t1 en res_t1 gebruiken ipv TRUNC + CURSOR c_del_doorbelast (p_rsv_ruimte_key IN NUMBER) + IS + SELECT soort, ref_key, oms, van, + fac.safe_to_number(SYSDATE - TRUNC(SYSDATE)) * 24 uren, + DECODE( exp_tijd, + NULL, van - exp_dagen, + DECODE( SIGN(exp_tijd - fac.safe_to_number(SYSDATE - TRUNC(SYSDATE)) * 24), + 1, TRUNC(van), + TRUNC(van) + 1 + ) + ) t_expire, + exp_dagen, exp_tijd, cnl_dagen + FROM ( + SELECT 'ruimte' soort, + rr.res_rsv_ruimte_key ref_key, + r.res_ruimte_nr oms, + rr.res_rsv_ruimte_van van, + dp.res_disc_params_kosten kosten, + dp.res_disc_params_expire_dagen exp_dagen, + dp.res_disc_params_expire_tijd exp_tijd, + dp.res_disc_params_cancel_dagen cnl_dagen + FROM res_rsv_ruimte rr, + res_ruimte_opstelling ro, + res_ruimte r, + res_discipline d, + res_disc_params dp + WHERE rr.res_rsv_ruimte_key = p_rsv_ruimte_key + AND ro.res_ruimte_opstel_key = rr.res_ruimte_opstel_key + AND r.res_ruimte_key = ro.res_ruimte_key + AND d.ins_discipline_key = r.res_discipline_key + AND dp.res_ins_discipline_key = d.ins_discipline_key + AND dp.res_disc_params_kosten > 0 + UNION ALL + SELECT 'artikel' soort, + ra.res_rsv_artikel_key, + a.res_artikel_omschrijving, + ra.res_rsv_artikel_levering, + dp.res_disc_params_kosten, + dp.res_disc_params_expire_dagen, + dp.res_disc_params_expire_tijd, + dp.res_disc_params_cancel_dagen + FROM res_rsv_artikel ra, + res_artikel a, + res_discipline d, + res_disc_params dp + WHERE ra.res_rsv_ruimte_key = p_rsv_ruimte_key + AND a.res_artikel_key = ra.res_artikel_key + AND d.ins_discipline_key = a.res_discipline_key + AND dp.res_ins_discipline_key = d.ins_discipline_key + AND dp.res_disc_params_kosten > 0 + UNION ALL + SELECT 'deel' soort, + rd.res_rsv_deel_key, + de.res_deel_omschrijving, + rd.res_rsv_deel_van, + dp.res_disc_params_kosten, + dp.res_disc_params_expire_dagen, + dp.res_disc_params_expire_tijd, + dp.res_disc_params_cancel_dagen + FROM res_rsv_deel rd, + res_deel de, + res_discipline d, + res_disc_params dp + WHERE rd.res_rsv_ruimte_key = p_rsv_ruimte_key + AND de.res_deel_key = rd.res_deel_key + AND d.ins_discipline_key = de.res_discipline_key + AND dp.res_ins_discipline_key = d.ins_discipline_key + AND dp.res_disc_params_kosten > 0); + + -- BIJWERKEN + -- Triggers voor het bijwerken van een bestaande toekomstige deelreservering: + -- - UPDATE-modifier in synchro, met bekend appointment-ID en bekende resource(s) (zonder bekende resource + -- krijgen we 'm niet eens binnen) + -- TODO: combi van appt_id, recur_id en room_id! + -- Dan checken of het nog wel om dezelfde resources (ruimtes) gaat, tijden zijn aangepast, deelnemers gewijzigd, + -- andere omschrijving, ... + -- - Omschrijving kan zonder notificatie aangepast worden + -- - Andere ruimte --> Moet er worden doorbelast? Voorwaarden voor catering hetzelfde (van MC naar OF bijv)? + -- TODO: notificeren + -- - Deelnemers erbij / eraf --> Bezoekers toevoegen / verwijderen, deelnemerslijst bijwerken. + -- TODO: notificeren + -- NB: checken of in deze synchro een appointment niet zowel bijgewerkt als verwijderd is; + -- dan hoeven we 'm natuurlijk niet meer bij te werken (weet niet of dat uberhaupt voorkomt met EWS) + -- TODO: dit detecteert geen room changes, alleen mutaties aan res op dezelfde ruimte. + CURSOR c_upd + IS + SELECT i.*, + rr.*, + rnew.res_ruimte_key, + rnew.res_ruimte_nr, + rnew.res_ruimte_extern_id, + rnew.res_discipline_key + FROM (SELECT room_id, + subject, + starttime, + endtime, + organizer, + modifier, + appt_id, + recur_id, + COUNT(*) num_bez + FROM demo_imp_exchange + WHERE modifier = 'U' + AND starttime > SYSDATE + AND gelukt IS NULL + AND NOT EXISTS (SELECT 1 + FROM res_ruimte + WHERE UPPER(res_ruimte_extern_id) = UPPER(att_mail) ) + GROUP BY recur_id, appt_id, room_id, subject, starttime, + endtime, organizer, modifier) i, + res_rsv_ruimte rr, + res_ruimte rnew + WHERE rr.res_rsv_ruimte_externnr LIKE i.appt_id||'|'||i.recur_id||'|%' + AND rr.res_rsv_ruimte_verwijder IS NULL + AND rnew.res_ruimte_extern_id = i.room_id + AND rnew.res_ruimte_verwijder IS NULL; + + -- TOEVOEGEN + -- Triggers voor het toevoegen van een toekomstige (deel)reservering: + -- - ADD-modifier in synchro; appointment is nieuw + -- - UPDATE-modifier in synchro, met onbekend appointment- en recurrence-ID voor deze room: dan (of) + -- - appointment bestond al, maar er is nu pas een ruimte aan toegevoegd; + -- - het was een single en nu recurring. + -- - appointment met meerdere ruimtes, maar nog geen deelreservering voor deze ruimte (zal vooral + -- voorkomen bij calendarview, als we de boekingen voor alle ruimtes op dit tijdstip binnenkrijgen -- + -- bij de synchro-import is dat niet gegarandeerd) + -- TODO: verwijderde deelreserveringen 'undeleten'? + CURSOR c_add + IS + SELECT i.*, + r.* + FROM (SELECT room_id, + subject, + starttime, + endtime, + organizer, + modifier, + appt_id, + recur_id, + seq_nr, + COUNT(*) num_bez + FROM demo_imp_exchange + WHERE modifier = 'C' + AND starttime > SYSDATE + AND gelukt IS NULL + AND NOT EXISTS (SELECT 1 + FROM res_ruimte + WHERE UPPER(res_ruimte_extern_id) = UPPER(att_mail) ) + GROUP BY recur_id, appt_id, seq_nr, room_id, subject, starttime, + endtime, organizer, modifier) i, + res_v_aanwezigruimte r + WHERE i.room_id = r.res_ruimte_extern_id + UNION ALL + SELECT i.*, + r.* + FROM (SELECT room_id, + subject, + starttime, + endtime, + organizer, + modifier, + appt_id, + recur_id, + seq_nr, + COUNT(*) num_bez + FROM demo_imp_exchange + WHERE modifier = 'U' + AND starttime > SYSDATE + AND gelukt IS NULL + AND NOT EXISTS (SELECT 1 + FROM res_ruimte + WHERE UPPER(res_ruimte_extern_id) = UPPER(att_mail) ) + GROUP BY recur_id, appt_id, seq_nr, room_id, subject, starttime, + endtime, organizer, modifier) i, + res_v_aanwezigruimte r + WHERE i.room_id = r.res_ruimte_extern_id + AND NOT EXISTS (SELECT 1 + FROM res_rsv_ruimte rr, + res_ruimte_opstelling ro, + res_ruimte r + WHERE rr.res_rsv_ruimte_externnr IS NOT NULL + AND rr.res_rsv_ruimte_externnr LIKE i.appt_id||'|'||i.recur_id||'|%' + AND rr.res_rsv_ruimte_verwijder IS NULL + AND ro.res_ruimte_opstel_key = rr.res_ruimte_opstel_key + AND r.res_ruimte_key = ro.res_ruimte_key + AND r.res_ruimte_verwijder IS NULL + AND r.res_ruimte_extern_id = i.room_id); + + BEGIN + -- We doen niets met boekingen in het verleden + UPDATE demo_imp_exchange i + SET gelukt = 4 + WHERE endtime < SYSDATE; + + -- En res_ruimtes als deelnemers, dat kan natuurlijk niet + UPDATE demo_imp_exchange i + SET gelukt = 5 + WHERE EXISTS (SELECT 1 + FROM res_ruimte + WHERE UPPER(res_ruimte_extern_id) = UPPER(att_mail) ); + + -- Eerst verwijderen; dat scheelt onterechte "dirties" bij toevoegen + -- Bij verplaatsen naar een andere ruimte krijg je mogelijk een delete op de oude + -- ruimte; die voeren we niet uit. Ook deletes van niet-bekende appointments negeren we. + UPDATE demo_imp_exchange i + SET gelukt = 3 + WHERE modifier IN ('D') + AND EXISTS (SELECT 1 FROM demo_imp_exchange + WHERE modifier != 'D' + AND appt_id||'|'||recur_id = i.appt_id||'|'||i.recur_id + AND seq_nr > i.seq_nr); + UPDATE demo_imp_exchange i + SET gelukt = 3 + WHERE modifier IN ('D') + AND NOT EXISTS (SELECT 1 FROM res_rsv_ruimte + WHERE res_rsv_ruimte_externnr LIKE i.appt_id||'|%'); + + FOR rec IN c_del + LOOP + BEGIN + v_aanduiding := rec.res_reservering_key||'/'||rec.res_rsv_ruimte_volgnr + ||' ('||rec.res_rsv_ruimte_key||'|'||rec.room_id || '|' || rec.subject||')'; + v_perslid_key := NULL; + v_kostenplaats_key := NULL; + v_rsv_ruimte_key := NULL; + v_status_fo_key := 1; + v_count := 0; + + -- Zie ook res_delete_save.asp + IF (v_debug) THEN + fac.imp_writelog (p_import_key, 'D', + v_aanduiding, 'VERWIJDEREN '||v_aanduiding); + END IF; + v_errorhint := 'Doorbelasting kosten'; + -- Moeten kosten worden doorbelast? + -- (I.e. zitten we binnen de expiretijd van een van de onderdelen?) + FOR rec_db IN c_del_doorbelast (rec.res_rsv_ruimte_key) + LOOP + v_count := v_count + 1; + END LOOP; + + -- Minstens een onderdeel moet worden doorbelast + -- FO-status van rsv_ruimte wordt "Vervallen" (4) + IF (v_count > 0) + THEN + v_status_fo_key := 4; + FOR rec_db IN c_del_doorbelast (rec.res_rsv_ruimte_key) + LOOP + IF (v_debug) THEN + fac.imp_writelog (p_import_key, 'D', + v_aanduiding, + rec_db.oms||' kosteloos annuleerbaar tot '|| + TO_CHAR(rec_db.t_expire, 'DD-MM-YYYY HH24:MI')); + END IF; + END LOOP; + END IF; + + v_errorhint := 'Deelreservering verwijderen'; + UPDATE res_rsv_ruimte + SET res_status_fo_key = v_status_fo_key, + res_rsv_ruimte_verwijder = SYSDATE + WHERE res_rsv_ruimte_key = rec.res_rsv_ruimte_key; + + fac.trackaction ('RESDEL', rec.res_rsv_ruimte_key, NULL, SYSDATE, NULL); + + res.set_ruimte_dirty(rec.res_rsv_ruimte_key); + res.set_ruimtes_clean(rec.res_rsv_ruimte_van); + res.follow_artikel(rec.res_rsv_ruimte_key, rec.res_rsv_ruimte_van, rec.res_rsv_ruimte_tot); + res.follow_deel(rec.res_rsv_ruimte_key, rec.res_rsv_ruimte_van, rec.res_rsv_ruimte_tot); + + v_errorhint := 'res_reservering verwijderen'; + UPDATE res_reservering + SET res_reservering_verwijder = SYSDATE + WHERE res_reservering_key = rec.res_reservering_key + AND NOT EXISTS (SELECT * + FROM res_v_aanwezigrsv_ruimte + WHERE res_reservering_key = rec.res_reservering_key); + + -- Succesvol afgerond; zet vlag. + -- AKZA#35459: vlag niet zetten voor een single die recurring is geworden; + -- die recurrence moeten we straks in de add-cursor nog toevoegen. + IF NOT (rec.reden = 'Made recurring') + THEN + UPDATE demo_imp_exchange + SET gelukt = 1 + WHERE appt_id||'|'||recur_id = rec.appt_id||'|'||rec.recur_id + AND gelukt IS NULL; + END IF; + + fac.imp_writelog (p_import_key, + 'I', + v_aanduiding, + 'Deelreservering verwijderd.' + ); + + EXCEPTION + WHEN OTHERS + THEN + v_count_error := v_count_error + 1; + oracle_err_num := SQLCODE; + oracle_err_mes := SUBSTR (SQLERRM, 1, 200); + v_errormsg := 'OTHERS (error ' + || oracle_err_num || '/' + || oracle_err_mes || ')'; + fac.imp_writelog (p_import_key, + 'E', + v_aanduiding, + v_errorhint||': '||v_errormsg + ); + END; + + END LOOP; + + COMMIT; + + -- Omdat we entries die gefaald zijn 'bewaren', kan het zijn dat we voor een appointment + -- meerdere updates - of zelfs een delete - hebben. Dan zijn we alleen geinteresseerd in de + -- nieuwste, de rest kan genegeerd/weg. (Als we een nieuwere UPDate hebben, kan de originele + -- ADD/create ook weg; een update van een nog-niet-bestaande reservering zorgt voor aanmaken.) + -- Hoger seq_nr = latere mutatie in Exchange + UPDATE demo_imp_exchange i + SET gelukt = 2 + WHERE modifier IN ('C', 'U') + AND EXISTS (SELECT 1 FROM demo_imp_exchange + WHERE appt_id||'|'||recur_id = i.appt_id||'|'||i.recur_id + AND fac_import_key != i.fac_import_key + AND seq_nr > i.seq_nr); + + -- Hetzelfde voor deletes van niet-bestaande reserveringen + UPDATE demo_imp_exchange i + SET gelukt = 2 + WHERE modifier = 'D' + AND NOT EXISTS (SELECT 1 FROM res_rsv_ruimte + WHERE res_rsv_ruimte_externnr LIKE i.appt_id||'|'||i.recur_id||'|%'); + + -- Dan bestaande bijwerken, anders kan het gebeuren dat we op basis van een UPDATE + -- eerst een rsv_ruimte aanmaken en 'm daarna meteen proberen bij te werken. + -- TODO: is dat nog steeds zo met "gelukt = 1"? + FOR rec IN c_upd + LOOP + BEGIN + v_aanduiding := rec.room_id || '|' || rec.subject || '|' || TO_CHAR(rec.starttime, 'DD-MM-YYYY HH24:MI') + || '-->'||rec.res_reservering_key||'/'||rec.res_rsv_ruimte_volgnr; + v_perslid_key := NULL; + v_kostenplaats_key := NULL; + v_rsv_ruimte_volgnr := 1; + v_rsv_ruimte_key := NULL; + v_count := NULL; + v_count_all_booked := NULL; + v_count_all_needed := NULL; + v_count_wanted := NULL; + v_ruimte_extern_id := NULL; + + -- Bepalen of dit een single-room of multi-room boeking is, door te achterhalen hoeveel ruimtes er in + -- FACILITOR geboekt (count_all_booked) zijn en hoeveel we er uit EWS hebben binnengekregen (count_all_needed). + -- Als count_all_booked > 1 en/of count_all_needed > 1, dan betreft het een appointment met meerdere + -- rooms en dus meerdere rsv_ruimtes. Dan moeten we nog meer weten. + -- Als count_all_booked = 1 en count_all_needed = 1, dan betreft het een single-room boeking en kunnen we + -- rucksichtslos bijwerken. + -- (Dat is niet correct als er een room aan een bestaande appointment is toegevoegd, waar we nu nog + -- maar een room van hebben. Maar de sync-functionaliteit van EWS biedt geen manier om die situatie te + -- achterhalen... Met de calendar view kan dit wel, omdat we dan alle gelijktijdige boekingen op de + -- verschillende ruimtes binnenkrijgen, daarom:) + -- Als we een full import doen (calendar view), kan het maar zo zijn dat we in de import meerdere + -- ruimtes in dezelfde appointment tegenkomen (count_all_needed > 1), terwijl we daar nu nog maar een + -- ruimte van kennen (count_all_booked = 1). Dan is het dus een multi-room boeking, die nog niets alszodanig + -- bekend stond. + v_errorhint := 'Totaal aantal geboekte zalen bepalen'; + SELECT COUNT(*) + INTO v_count_all_booked + FROM res_rsv_ruimte rr + WHERE rr.res_rsv_ruimte_externnr LIKE rec.appt_id||'|'||rec.recur_id||'|%' + AND rr.res_rsv_ruimte_verwijder IS NULL; + + v_errorhint := 'Totaal aantal benodigde zalen bepalen'; + SELECT COUNT(DISTINCT room_id) + INTO v_count_all_needed + FROM demo_imp_exchange i + WHERE i.modifier IN ('U', 'C') + AND i.starttime > SYSDATE + AND i.appt_id||'|'||i.recur_id||'|' LIKE rec.appt_id||'|'||rec.recur_id||'|'; + + -- De cursor bevat voor iedere appointment alle rsv_ruimtes met dezelfde appt_id en recur_id. + -- Er zal hoogstens een rsv_ruimte op de betreffende room zijn. + -- Bestaat er al een rsv_ruimte voor deze room (count = 1)? + v_errorhint := 'Bepalen of zaal al geboekt is'; + SELECT COUNT(*) + INTO v_count + FROM res_rsv_ruimte rr, + res_ruimte_opstelling rops, + res_ruimte r + WHERE rr.res_rsv_ruimte_externnr LIKE rec.appt_id||'|'||rec.recur_id||'|%' + AND rr.res_rsv_ruimte_verwijder IS NULL + AND rops.res_ruimte_opstel_key = rr.res_ruimte_opstel_key + AND r.res_ruimte_key = rops.res_ruimte_key + AND r.res_ruimte_extern_id = rec.room_id; + + -- Als er al een rsv_ruimte voor deze room is, is dat dan degene die we nu in de cursor hebben? + -- Zo ja, dan willen we die bijwerken. + -- Zo nee, dan doen we niets + v_errorhint := 'Bepalen zaal huidige deelreservering'; + SELECT r.res_ruimte_extern_id + INTO v_ruimte_extern_id + FROM res_rsv_ruimte rr, + res_ruimte_opstelling ro, + res_ruimte r + WHERE rr.res_rsv_ruimte_key = rec.res_rsv_ruimte_key + AND ro.res_ruimte_opstel_key = rr.res_ruimte_opstel_key + AND r.res_ruimte_key = ro.res_ruimte_key + AND r.res_ruimte_verwijder IS NULL; + + -- De room is nog niet geboekt. Dan kunnen we of een bestaande boeking omhangen naar deze ruimte, + -- of een nieuwe boeking maken (in de ADD-cursor) + -- Daarom: kunnen we de huidige rsv_ruimte aanpassen, of is die ruimte nog gewoon geboekt in Exchange? + v_errorhint := 'Bepalen of voor room/zaal nog een boeking gewenst is'; + SELECT COUNT(DISTINCT room_id) + INTO v_count_wanted + FROM demo_imp_exchange i + WHERE appt_id||'|'||recur_id||'|' = rec.appt_id||'|'||rec.recur_id||'|' + AND room_id = v_ruimte_extern_id; + + IF (v_debug) THEN + fac.imp_writelog (p_import_key, 'D', + v_aanduiding, + v_count_all_booked||' deelreservering(en) bij deze appointment ('|| + v_count_all_needed||' nodig), waarvan '||v_count||' voor deze room' + ); + END IF; + + -- NB: Deze oplossing is niet waterdicht. Daarvoor moet je eigenlijk weten in welke room een appointment + -- eerst was. Het lijkt handig om daarvoor uit de EWS-XML de Location en OldLocation nodes + -- te gebruiken, omdat daarin alle uitgenodigde ruimtes uitgelijst staan, maar helaas is Location + -- aanpasbaar in Outlook... + + -- Multi-room? Dan nog wat checks, anders 'gewoon' bijwerken. + IF (v_count_all_booked > 1 OR v_count_all_needed > 1) + THEN + IF (v_debug) + THEN + fac.imp_writelog (p_import_key, 'D', + v_aanduiding, + 'Deze deelres. is op '||v_ruimte_extern_id|| + '. Benodigde deelres.: '||v_count_all_needed|| + ', waarvan op deze ruimte: '||v_count_wanted + ); + END IF; + -- Hebben we al een boeking voor deze zaal? + IF (v_count = 1) + THEN + -- Met deze rsv_ruimte? + -- Zo niet, dan skippen. + -- Zo ja, dan bijwerken (hier niets doen) + IF (v_ruimte_extern_id != rec.res_ruimte_extern_id) + THEN + IF (v_debug) THEN + fac.imp_writelog (p_import_key, 'D', + v_aanduiding, + 'Skip (boeking op deze ruimte met andere rsv_ruimte)' + ); + END IF; + CONTINUE; + END IF; + ELSIF (v_count = 0) + THEN + -- Willen we de ruimte van deze rsv_ruimte nog? + -- Zo ja, dan skippen. + -- Zo niet, dan kunnen we deze rsv_ruimte bijwerken (hier niets doen) + IF (v_count_wanted > 0) + THEN + IF (v_debug) THEN + fac.imp_writelog (p_import_key, 'D', + v_aanduiding, + 'Skip (deze boeking ''bewaren'')' + ); + END IF; + CONTINUE; + END IF; + END IF; + END IF; + + -- We hebben niet geskipt, dus willen we deze rsv_ruimte bijwerken + -- Basisgegevens reservering gewijzigd? + IF ( v_ruimte_extern_id != rec.res_ruimte_extern_id + OR rec.res_rsv_ruimte_omschrijving != SUBSTR(rec.subject, 1, 60) + OR rec.res_rsv_ruimte_bezoekers != rec.num_bez + OR rec.res_rsv_ruimte_van != rec.starttime + OR rec.res_rsv_ruimte_tot != rec.endtime) + THEN + v_errorhint := 'Opstelling ophalen'; + v_ruimte_opstel_key := demo.getOpstelling(rec.room_id); + IF (v_ruimte_opstel_key IS NULL) + THEN + fac.imp_writelog (p_import_key, + 'E', + v_aanduiding, + 'Geen ruimte-opstelling gedefinieerd' + ); + CONTINUE; + END IF; + + v_errorhint := 'Basisgegevens bijwerken'; + UPDATE res_rsv_ruimte + SET res_ruimte_opstel_key = v_ruimte_opstel_key, + res_rsv_ruimte_omschrijving = SUBSTR(rec.subject, 1, 60), + res_rsv_ruimte_van = rec.starttime, + res_rsv_ruimte_tot = rec.endtime, + res_rsv_ruimte_bezoekers = rec.num_bez + WHERE res_rsv_ruimte_key = rec.res_rsv_ruimte_key; + + -- Opruimen en voorzieningen en bezoekers laten volgen + v_errorhint := 'Dirty, clean, voorzieningen'; + res.set_ruimte_dirty(rec.res_rsv_ruimte_key); + res.set_ruimtes_clean(rec.starttime); + res.follow_artikel(rec.res_rsv_ruimte_key, rec.res_rsv_ruimte_van, rec.res_rsv_ruimte_tot); + res.follow_deel(rec.res_rsv_ruimte_key, rec.res_rsv_ruimte_van, rec.res_rsv_ruimte_tot); + res.follow_afspraak(rec.res_rsv_ruimte_key, 0); + + --TODO: tracking + notificatie + IF (v_debug) THEN + fac.imp_writelog (p_import_key, 'D', + v_aanduiding, 'RES: '||rec.res_reservering_key||'/'||rec.res_rsv_ruimte_volgnr); + fac.imp_writelog (p_import_key, 'D', + v_aanduiding, 'Room: '||v_ruimte_extern_id||'-->'||rec.res_ruimte_extern_id); + fac.imp_writelog (p_import_key, 'D', + v_aanduiding, 'Desc: "'||rec.res_rsv_ruimte_omschrijving||'"-->"'||SUBSTR(rec.subject, 1, 60)||'"'); + fac.imp_writelog (p_import_key, 'D', + v_aanduiding, 'Start: '||TO_CHAR(rec.res_rsv_ruimte_van,'DD-MM-YYYY HH24:MI')||'-->'||TO_CHAR(rec.starttime,'DD-MM-YYYY HH24:MI')); + fac.imp_writelog (p_import_key, 'D', + v_aanduiding, 'Einde: '||TO_CHAR(rec.res_rsv_ruimte_tot,'DD-MM-YYYY HH24:MI')||'-->'||TO_CHAR(rec.endtime,'DD-MM-YYYY HH24:MI')); + fac.imp_writelog (p_import_key, 'D', + v_aanduiding, 'Bezoekers: '||rec.res_rsv_ruimte_bezoekers||'-->'||rec.num_bez); + END IF; + + fac.trackaction ('RESUPD', rec.res_rsv_ruimte_key, NULL, SYSDATE, NULL); + fac.imp_writelog (p_import_key, + 'I', + v_aanduiding, + 'Reservering bijgewerkt' + ); + ELSE + IF (v_debug) THEN + fac.imp_writelog (p_import_key, 'D', + v_aanduiding, 'Geen verschil in basisgegevens'); + END IF; + END IF; + + -- Bezoekers bijwerken + v_errorhint := 'Bezoekers bijwerken'; + demo.setBezoekers(p_import_key, rec.appt_id, rec.recur_id, rec.res_rsv_ruimte_key); + + -- Succesvol afgerond; zet vlag. + -- Alleen voor nu beschouwde ruimte! (appointments kunnen op meerdere ruimtes zijn) + -- TODO: komen we hier ook als er iets mis ging met de bezoekers? + UPDATE demo_imp_exchange + SET gelukt = 1 + WHERE appt_id||'|'||recur_id = rec.appt_id||'|'||rec.recur_id + AND room_id = rec.room_id + AND gelukt IS NULL; + + IF (v_debug) THEN + fac.imp_writelog (p_import_key, 'D', + v_aanduiding, 'gelukt=1'); + END IF; + + EXCEPTION + WHEN OTHERS + THEN + v_count_error := v_count_error + 1; + oracle_err_num := SQLCODE; + oracle_err_mes := SUBSTR (SQLERRM, 1, 200); + v_errormsg := 'OTHERS (error ' + || oracle_err_num || '/' + || oracle_err_mes || ')'; + fac.imp_writelog (p_import_key, + 'E', + v_aanduiding, + v_errorhint||': '||v_errormsg + ); + END; + + END LOOP; + + COMMIT; + + -- Ten slotte nieuwe reserveringen toevoegen + FOR rec IN c_add + LOOP + BEGIN + v_aanduiding := rec.room_id || '|' || rec.subject; + v_perslid_key := NULL; + v_kostenplaats_key := NULL; + v_reservering_key := NULL; + v_rsv_ruimte_volgnr := 1; + v_rsv_ruimte_key := NULL; + + v_errorhint := 'Host ' || rec.organizer || ' onbekend, of meer personen met dit e-mailadres! Geen boeking.'; + -- Kennen we deze persoon eigenlijk wel? + SELECT COUNT(*) + INTO v_count + FROM prs_v_aanwezigperslid p + WHERE UPPER(p.prs_perslid_email) = UPPER(rec.organizer); + + -- Niet bekend, of niet eenduidig --> jammer dan. + IF (v_count != 1) + THEN + fac.imp_writelog (p_import_key, + 'E', + v_errorhint, + v_aanduiding + ); + -- Eenduidig bekend --> reservering maken + ELSE + v_errorhint := 'Persoonsgegevens ophalen'; + SELECT p.prs_perslid_key, a.prs_kostenplaats_key + INTO v_perslid_key, v_kostenplaats_key + FROM prs_v_aanwezigperslid p, + prs_v_aanwezigafdeling a + WHERE UPPER(p.prs_perslid_email) = UPPER(rec.organizer) + AND a.prs_afdeling_key = p.prs_afdeling_key; + + v_errorhint := 'Opstelling ophalen'; + v_ruimte_opstel_key := demo.getOpstelling(rec.room_id); + IF (v_ruimte_opstel_key IS NULL) + THEN + fac.imp_writelog (p_import_key, + 'E', + v_aanduiding, + 'Geen ruimte-opstelling gedefinieerd' + ); + CONTINUE; + END IF; + + -- Is dit een op zichzelf staande appointment, of onderdeel van een reeks (recurrence)? + -- (obv recur_id, die samen met appt_id in res_rsv_ruimte_externnr staat) + v_errorhint := 'Check recurrence'; + SELECT COUNT(*) + INTO v_count + FROM res_rsv_ruimte + WHERE res_rsv_ruimte_externnr IS NOT NULL + AND res_rsv_ruimte_externnr LIKE rec.appt_id||'|%' +-- AND res_rsv_ruimte_externnr NOT LIKE '%|'||rec.recur_id||'|%' + AND res_rsv_ruimte_verwijder IS NULL; + + -- Er bestaan al deelreserveringen voor andere occurences van deze recurring appointment + -- Deelreservering binnen de bijbehorende res_reservering aanmaken + IF (v_count > 0) + THEN + v_errorhint := 'Reservering + volgnr ophalen'; + SELECT res_reservering_key, MAX(res_rsv_ruimte_volgnr)+1 + INTO v_reservering_key, v_rsv_ruimte_volgnr + FROM res_rsv_ruimte + WHERE res_rsv_ruimte_externnr IS NOT NULL + AND res_rsv_ruimte_externnr LIKE rec.appt_id||'|%' +-- AND res_rsv_ruimte_externnr NOT LIKE '%|'||rec.recur_id||'|%' + AND res_rsv_ruimte_verwijder IS NULL + GROUP BY res_reservering_key; + + fac.imp_writelog (p_import_key, + 'I', + v_aanduiding, + 'Is occurence van '||v_reservering_key + ); + -- Nog geen andere occurences --> nieuwe res_reservering + ELSE + v_errorhint := 'Reservering aanmaken'; + -- res_reservering aanmaken + INSERT INTO res_reservering + (res_reservering_ispool) + VALUES (0) + RETURNING res_reservering_key + INTO v_reservering_key; + END IF; + + v_errorhint := 'Deelreservering aanmaken'; + -- res_rsv_ruimte aanmaken voor deze appointment+resource + INSERT INTO res_rsv_ruimte ( + res_rsv_ruimte_omschrijving, + res_rsv_ruimte_opmerking, + res_rsv_ruimte_externnr, + res_ruimte_opstel_key, + res_rsv_ruimte_van, + res_rsv_ruimte_tot, + prs_kostenplaats_key, + res_rsv_ruimte_host_key, + res_activiteit_key, + res_status_fo_key, + res_rsv_ruimte_ordernr, + res_rsv_ruimte_kosten_klant, + res_rsv_ruimte_contact_key, + res_rsv_ruimte_bezoekers, + res_reservering_key, + res_rsv_ruimte_volgnr, + res_status_bo_key) + VALUES ( + SUBSTR(rec.subject, 1, 60), + NULL, + rec.appt_id||'|'||rec.recur_id||'|'||rec.seq_nr, + v_ruimte_opstel_key, + rec.starttime, + rec.endtime, + v_kostenplaats_key, + v_perslid_key, + c_activiteit_key, + 2, + NULL, + 1, + v_perslid_key, + rec.num_bez, + v_reservering_key, + v_rsv_ruimte_volgnr, + 2) + RETURNING res_rsv_ruimte_key + INTO v_rsv_ruimte_key; + + IF (v_debug) THEN + fac.imp_writelog (p_import_key, 'D', + v_aanduiding, 'RESERVERING '||v_reservering_key||'/'||v_rsv_ruimte_volgnr||' ('||v_rsv_ruimte_key||')'); + END IF; + + v_errorhint := 'Toevoegen bezoekers'; + demo.setBezoekers(p_import_key, rec.appt_id, rec.recur_id, v_rsv_ruimte_key); + + -- Succesvol afgerond; zet vlag. + -- TODO: komen we hier ook als er iets mis ging met de bezoekers? + UPDATE demo_imp_exchange + SET gelukt = 1 + WHERE appt_id||'|'||recur_id = rec.appt_id||'|'||rec.recur_id + AND gelukt IS NULL; + + IF (v_debug) THEN + fac.imp_writelog (p_import_key, 'D', + v_aanduiding, 'gelukt=1'); + END IF; + + -- res_discipline achterhalen; alleen tracken voor EXCO en MC zalen + v_errorhint := 'res_discipline bepalen'; + SELECT r.res_discipline_key + INTO v_discipline_key + FROM res_ruimte r, + res_ruimte_opstelling ro, + res_rsv_ruimte rr + WHERE rr.res_rsv_ruimte_key = v_rsv_ruimte_key + AND ro.res_ruimte_opstel_key = rr.res_ruimte_opstel_key + AND r.res_ruimte_key = ro.res_ruimte_key; + + -- Altijd tracken, maar alleen notificeren als niet discipline 1485 + -- AKZA#40274 ook notificeren als discipline = 1485 Mail Andre 6-7: voorlopig terugdraaien + -- DEMO#57950: Bovenstaande nog even laten staan. Voor Schiphol + -- geldt altijd tracken en notificeren! + v_errorhint := 'Tracking NEW'; + v_code := 'RESNEW'; + --IF (v_discipline_key = 1341) + --THEN + -- v_code := '#RESNEW'; + --END IF; + fac.trackaction (v_code, v_rsv_ruimte_key, NULL, SYSDATE, 'Uw reservering '||TO_CHAR(v_reservering_key)||'/'||TO_CHAR(v_rsv_ruimte_volgnr)||' is geregistreerd'); + -- Is er iets dirty? + res.set_ruimte_dirty(v_rsv_ruimte_key); + + fac.imp_writelog (p_import_key, + 'I', + v_reservering_key||'/'||v_rsv_ruimte_volgnr + ||'('||TO_CHAR(rec.starttime, 'DD-MM-YYYY HH24:MI') + ||' - '||TO_CHAR(rec.endtime, 'HH24:MI') + ||') aangemaakt', + rec.subject + ); + COMMIT; + END IF; + + EXCEPTION + WHEN OTHERS + THEN + v_count_error := v_count_error + 1; + oracle_err_num := SQLCODE; + oracle_err_mes := SUBSTR (SQLERRM, 1, 200); + v_errormsg := 'OTHERS (error ' + || oracle_err_num || '/' + || oracle_err_mes || ')'; + fac.imp_writelog (p_import_key, + 'E', + v_aanduiding, + v_errorhint||': '||v_errormsg + ); + END; + + END LOOP; + -- Bij dirty ruimtes de *oudere* opruimen + v_aanduiding := 'Calling set_ruimtes_clean'; + v_errorhint := ''; + demo.set_ruimtes_clean(p_import_key); + COMMIT; + +EXCEPTION + WHEN OTHERS + THEN + v_count_error := v_count_error + 1; + oracle_err_num := SQLCODE; + oracle_err_mes := SUBSTR (SQLERRM, 1, 200); + v_errormsg := 'OTHERS (error ' + || oracle_err_num || '/' + || oracle_err_mes || ')'; + fac.imp_writelog (p_import_key, + 'E', + v_aanduiding, + v_errorhint||': '||v_errormsg + ); + COMMIT; +END demo_update_exchange; +/ + + +CREATE OR REPLACE PROCEDURE demo_import_exchsync (p_import_key IN NUMBER) +AS +BEGIN + demo_import_exchange(p_import_key); +END; +/ + +CREATE OR REPLACE PROCEDURE demo_update_exchsync (p_import_key IN NUMBER) +AS +BEGIN + demo_update_exchange(p_import_key); +END; +/ + + + ------------------------------------------ CREATE OR REPLACE VIEW demo_v_mld_inkoopaanvraag