-- Customer specific once-script RWSN52.
--
-- (c) 2013 SG|facilitor bv
-- $Revision$
-- $Id$
--
-- Support: +31 53 4800700
SET ECHO ON
SPOOL xrwsn52.lst
SET DEFINE OFF

-- RWSN#27455: Aanpassing IDM-koppeling (van BSN naar RIN); tbv. levering naar
--             Test nu nog in rwsn52, maar later (TODO) opnemen in rwsn.sql!!!
CREATE OR REPLACE PROCEDURE rwsn_update_idm_pers (p_import_key IN NUMBER)
AS
   /*  Globale werking:
       Op basis van het IDM importbestand
      -- worden personen toegevoegd aan (vereist) bestaande afdelingen
      -- worden onderwijl functie aangemaakt, zonodig
      -- worden werkplekken gedefinieerd zomogelijk (vertaaltabel)
      -- worden vervallen personen verwijderd
      (c) SG|facilitor bv
   */
   -- Constanten
   c_verdieping_omschr_default   VARCHAR2 (16)                        := 'Begane grond';
   c_srtruimte_default           INTEGER                              := 1;
   c_ruimte_code                 VARCHAR2 (3)                         := '001';
   c_ruimte_omschr_default       VARCHAR2 (16)                        := 'Onbekend';
   c_werkplek_volgnr_default     INTEGER                              := 1;
   c_prs_werkplek_omschrijving   VARCHAR2 (16)                        := '1';
   c_default_profiel_key         NUMBER (10)                          := 1;
   c_rin_kkey                    NUMBER (10)                          := 1160;
   c_commitbuffer                NUMBER                               := 1000;
   -- om de zoveel committen
   v_buffercount                 NUMBER                               := 0;

   -- Personen die moeten vervallen zijn personen die:
   --- volgens de importregels zijn ingevoerd (ignore handmatige)
   --- in de import voorkomen en een einddatum hebben die voorbij is
   --- of niet in de import voorkomen
   -- en die nog niet vervallen waren
   -- personeelsnummer=BSN uit de importtabel mapt op prs_perslid_authenticatie => per RWSN52 vervallen!
   -- RIN uit de importtabel mapt op kenmerk met key=1160
   -- dienstverbandid uit de importtabel (SAPHRnummer) mapt op prs_perslid_nr
   CURSOR c_prs_del
   IS
      SELECT   p.prs_perslid_key,
               pf.prs_perslid_naam_full,
               kl.prs_kenmerklink_waarde rin
        FROM   prs_perslid p,
               prs_v_perslid_fullnames_all pf,
               prs_v_aanwezigkenmerklink kl
       WHERE       p.prs_perslid_verwijder IS NULL    -- is niet al verwijderd
               AND p.prs_perslid_key = pf.prs_perslid_key
               AND p.prs_perslid_key = kl.prs_link_key
               AND kl.prs_kenmerk_key = c_rin_kkey     -- is ooit geimporteerd
               AND NOT EXISTS                      -- komt niet voor in import
                     (SELECT   1
                        FROM   rwsn_imp_idm_pers
                       WHERE   UPPER (rin) = UPPER (kl.prs_kenmerklink_waarde))
      UNION ALL
      SELECT   p.prs_perslid_key,
               pf.prs_perslid_naam_full,
               kl.prs_kenmerklink_waarde rin
        FROM   prs_perslid p,
               prs_v_perslid_fullnames_all pf,
               prs_v_aanwezigkenmerklink kl
       WHERE       p.prs_perslid_verwijder IS NULL    -- is niet al verwijderd
               AND p.prs_perslid_key = pf.prs_perslid_key
               AND p.prs_perslid_key = kl.prs_link_key
               AND kl.prs_kenmerk_key = c_rin_kkey     -- is ooit geimporteerd
               AND NOT EXISTS -- is beeindigd volgens import (geen persoon-regels met einddatum in toekomst)
                     (SELECT   1
                        FROM   rwsn_imp_idm_pers
                       WHERE   UPPER (rin) = UPPER (kl.prs_kenmerklink_waarde)
                               AND COALESCE (einddatum,SYSDATE + 1) > SYSDATE)
      ORDER BY   3, 1;

   -- Personen die nieuw of gewijzigd zijn
   --- Reeds eerder verwijderde personen kunnen worden gereactiveerd (.. check)
   -- Dubbele dienstverbanden wordt achter elkaar ingelezen en overschrijven elkaar dus.
   -- In de volgorde is de laatste einddatum het laatst aan de beurt. Dit is vaak het
   -- permanente contract tot jaar 9999.
   CURSOR c_prs_upd
   IS
        SELECT   p.prs_perslid_key, idm.locatiecode alg_locatie_code, idm.afdelingscode prs_afdeling_naam,
                 idm.persoonachternaam prs_perslid_naam, idm.tussenvoegsel prs_perslid_tussenvoegsel,
                 idm.voorletters prs_perslid_voorletters, idm.voornaam prs_perslid_voornaam,
                 idm.telefoonnummer prs_perslid_telefoonnr, idm.functie prs_srtperslid_omschrijving, idm.rin,
                 idm.personeelsnummer personeelsnummer, idm.titel prs_perslid_titel, p.prs_perslid_verwijder,
                 idm.begindatum, idm.einddatum, idm.mobielnummer, idm.email, idm.loginnaam, idm.dienstverbandguid,
                 idm.dienstverbandid, idm.bezoekadresnaam, idm.bezoekadresnummer, idm.bezoekadrespostcode,
                 idm.bezoekadresplaats, idm.aanduidingnaamgebruik, idm.partnertussenvoegsel, idm.partnernaam
          FROM      (SELECT   *
                       FROM   rwsn_imp_idm_pers
                      WHERE   einddatum > SYSDATE) idm
                 LEFT JOIN
                    (SELECT   kl.prs_kenmerklink_waarde rin,
                              p.prs_perslid_key,
                              p.prs_perslid_verwijder
                       FROM   prs_perslid p, prs_v_aanwezigkenmerklink kl
                      WHERE   p.prs_perslid_key = kl.prs_link_key
                              AND kl.prs_kenmerk_key = c_rin_kkey) p
                 ON idm.rin = p.rin
      ORDER BY   idm.rin, idm.einddatum, prs_perslid_key DESC;

   v_perslid_key                 NUMBER (10);
   v_prs_key_cnt                 NUMBER (10);
   v_srtperslid_key              NUMBER (10);
   v_afdeling_key                NUMBER (10);
   v_srtperslid_omschr           VARCHAR2 (30);
   oracle_err_num                NUMBER;
   oracle_err_mes                VARCHAR2 (200);
   v_errormsg                    VARCHAR2 (1000);
   v_errorhint                   VARCHAR2 (1000);
   v_count                       NUMBER (10);
   v_update                      BOOLEAN;
   v_perslid_count_imp           NUMBER;
   v_perslid_count_fclt          NUMBER;
   v_perslid_newcount_fclt       NUMBER;
   currentversion                fac_module.fac_module_version%TYPE;
   v_newgebouwkey                NUMBER;
   lnaampresentatie              VARCHAR2 (100);
   ltussenvoegselpres            VARCHAR2 (100);
   lemail                        VARCHAR2 (100);
   llogin1                       VARCHAR2 (100);
   llogin2                       VARCHAR2 (100);


   -- Bepaal het gebouw behorende bij postcode en nummer (best guess!)
   -- Return -1 als het niet bepaald kan worden
   FUNCTION getgebouwkey (postcode IN VARCHAR2, nummer IN VARCHAR2)
      RETURN NUMBER
   IS
      llocatiekey   alg_locatie.alg_locatie_key%TYPE;
      lgebouwkey    alg_gebouw.alg_gebouw_key%TYPE;
   BEGIN
      IF postcode IS NULL
      THEN
         RETURN -1;
      END IF;

      SELECT NVL (MIN (alg_locatie_key), -1)
        INTO llocatiekey
        FROM mld_adres m
       WHERE m.mld_adres_bezoek_postcode = postcode
         AND UPPER(SUBSTR(RTRIM(m.mld_adres_bezoek_adres), INSTR(RTRIM(m.mld_adres_bezoek_adres), ' ', -1)+1))
           = UPPER(nummer) ;

      IF llocatiekey <> -1
      THEN
         SELECT NVL (MIN (alg_gebouw_key), -1)
           INTO lgebouwkey
           FROM alg_gebouw
          WHERE alg_gebouw_verwijder IS NULL AND alg_locatie_key = llocatiekey;
      ELSE
         lgebouwkey := -1;
      END IF;

      RETURN lgebouwkey;
   END;

   -- Het login veld in het importbestand heeft de onzalige eigenschap
   -- dat er soms meerdere in staan, gescheiden door een , (komma)
   -- Deze functie vertaalt dit veld tot een goede login
   -- Op dit moment is dat het eerste adres. Tenzij de bestaande login voorkomt
   -- in de lijst.
   PROCEDURE handle_login (plogin IN VARCHAR2, p_perslid_key IN NUMBER, login1 OUT VARCHAR2, login2 OUT VARCHAR2)
   IS
      l_login_str                rwsn_imp_idm_pers.loginnaam%TYPE;
   BEGIN
      l_login_str := UPPER(plogin);
      IF p_perslid_key IS NOT NULL THEN
         -- bestaand persoon
         SELECT prs_perslid_oslogin, prs_perslid_oslogin2
           INTO login1, login2
           FROM prs_perslid
          WHERE prs_perslid_key = p_perslid_key;
         IF login1 = login2 THEN
           login2 := NULL;
         END IF;
         IF login1 IS NOT NULL AND INSTR(','||l_login_str||',', ','||login1||',') > 0 THEN
            -- 1e login is niet leeg en is gevonden in login lijst
            -- we hoeven niets te doen
            NULL;
         ELSE
            -- 1e login is niet gevonden of is leeg
            -- controleer of er meerdere logins op de regel staan
            IF INSTR (l_login_str, ',') > 0 THEN
              login1 := SUBSTR (l_login_str, 1, INSTR (l_login_str, ',') - 1);
            ELSE
              login1 := l_login_str;
            END IF;
            IF login1 = login2 THEN
               login2 := NULL;
            END IF;
         END IF;

         IF login2 IS NOT NULL AND INSTR(','||l_login_str||',', ','||login2||',') > 0 THEN
            -- 2e login is niet leeg en is gevonden in login lijst
            -- we hoeven niets te doen
            NULL;
         ELSE
            -- 2e login is niet gevonden of is leeg
            login2 := SUBSTR (l_login_str, 1, INSTR (l_login_str, ',') - 1);
            IF login1 = login2 THEN
               -- ga op zoek naar de volgende
               l_login_str := SUBSTR(l_login_str, INSTR (l_login_str, ',')+1);
               IF INSTR (l_login_str, ',') > 0 THEN
                 login2 := SUBSTR (l_login_str, 1, INSTR (l_login_str, ',') - 1);
               ELSE
                 login2 := l_login_str;
               END IF;
            END IF;
         END IF;

      ELSE

        IF INSTR (l_login_str, ',') > 0
        THEN
           login1 := SUBSTR (l_login_str, 1, INSTR (l_login_str, ',') - 1);
           l_login_str := SUBSTR(l_login_str, INSTR (l_login_str, ',')+1);
           IF INSTR (l_login_str, ',') > 0 THEN
             login2 := SUBSTR (l_login_str, 1, INSTR (l_login_str, ',') - 1);
           ELSE
             login2 := l_login_str;
           END IF;
        ELSE
           login1 := l_login_str;
           login2 := null;
        END IF;
      END IF;
   END;

   -- Het emailveld in het importbestand heeft de onzalige eigenschap
   -- dat er soms meerdere in staan, gescheiden door een , (komma)
   -- Deze functie vertaalt dit veld tot een goed emailadressen
   -- Op dit moment nemen we alle email adressen over zodat de
   -- gebruiker meerdere mailtjes krijgt.
   FUNCTION handle_email (pemail IN VARCHAR2)
      RETURN VARCHAR2
   IS
      rstr   rwsn_imp_idm_pers.email%TYPE;
   BEGIN
      rstr := pemail;
      RETURN rstr;
   END;

   -- Procedure die alles regelt voor de locatie van een persoon, varierend van
   -- NIKS: als plaats ongeldig is of de huidige situatie al goed is
   -- ZETTEN OP EEN BESTAANDE WERKPLEK
   -- VERDIEPING/RUIMTE/WERKPLEK AANMAKEN EN TOEKENNEN
   PROCEDURE handle_location (pkey IN NUMBER, pgebouwkey IN VARCHAR2, prin IN VARCHAR2)
   IS
      lv_errormsg             VARCHAR2 (1000);
      lv_errorhint            VARCHAR2 (1000);
      lv_nr_werkplek          NUMBER;
      lv_current_gebouw_key   NUMBER;
      lv_verdieping_key       NUMBER (10);
      lv_ruimte_key           NUMBER (10);
      lv_werkplek_key         NUMBER (10);
   BEGIN
      lv_errormsg := 'Toekennen van een plaats';

      IF pgebouwkey = -1
      THEN
         lv_errorhint := 'Onbekend gebouw voor persoon/RIN: ' || prin;
         fac.imp_writelog (p_import_key, 'W', lv_errormsg, lv_errorhint);
         RETURN;
      END IF;

       -- komt de nieuwe werkplek al voor bij een van de bestaande werkplekken?
       SELECT COUNT (*)
         INTO lv_nr_werkplek
         FROM prs_perslidwerkplek pw, prs_werkplek w, alg_ruimte r, alg_verdieping v
        WHERE pw.prs_werkplek_key = w.prs_werkplek_key
          AND nvl(w.prs_werkplek_virtueel, 0) <> 1
          AND w.prs_alg_ruimte_key = r.alg_ruimte_key
          AND r.alg_verdieping_key = v.alg_verdieping_key
          AND prs_perslid_key = pkey
          AND v.alg_gebouw_key = pgebouwkey;

      IF lv_nr_werkplek > 0
      THEN
         -- nieuwe werkplek bestaat al als een van de werkplekken.
         lv_errorhint := 'Ongewijzigd gebouw voor persoon/RIN: ' || prin;
         fac.imp_writelog (p_import_key, 'I', lv_errormsg, lv_errorhint);
         RETURN;
      END IF;

      -- verwijder de bestaande werkplekken.
      -- HdZ (6-8-2009: werkplekken mogen nog niet verwijderd worden via de koppeling.
      --                werkplekken worden nog vaak handmatig aangemaakt.
      --DELETE prs_perslidwerkplek WHERE prs_perslid_key = pkey;

      -- Er moet wat gebeuren, plaatsen of verplaatsen
      -- Vooralsnog even (bij)plaatsen
      -- De gebouwkey is bekend, dus het gebouw ook.
      -- Dan zoeken we naar de laagste verdieping en laagste ruimtenr
      -- en dan maken we daarvoor een werkplek aan
      IF lv_nr_werkplek = 0
      THEN
         -- persoon heeft geen werkplek(ken)
         BEGIN
            lv_errormsg := 'Bepalen verdieping';

            SELECT alg_verdieping_key
              INTO lv_verdieping_key
              FROM alg_verdieping
             WHERE alg_gebouw_key = pgebouwkey AND alg_verdieping_verwijder IS NULL AND alg_verdieping_upper like '%BEGANE GROND%';
         EXCEPTION
            WHEN NO_DATA_FOUND
            THEN
               v_errorhint := 'Begane grond toevoegen voor persoon/RIN: ' || prin;

               INSERT INTO alg_verdieping
                           (alg_gebouw_key, alg_verdieping_omschrijving, alg_verdieping_volgnr, alg_verdieping_code)
                    VALUES (pgebouwkey, c_verdieping_omschr_default, 0, '0')
                 RETURNING alg_verdieping_key
                      INTO lv_verdieping_key;
         END;

         -- lv_verdieping_key bekend
         BEGIN
            -- zoek de laagste ruimte op deze verdieping
            SELECT alg_ruimte_key
              INTO lv_ruimte_key
              FROM alg_ruimte
             WHERE alg_verdieping_key = lv_verdieping_key
               AND alg_ruimte_verwijder IS NULL
               AND alg_ruimte_nr = (SELECT MIN (alg_ruimte_nr)
                                      FROM alg_ruimte
                                     WHERE alg_verdieping_key = lv_verdieping_key AND alg_ruimte_verwijder IS NULL);
         EXCEPTION
            WHEN NO_DATA_FOUND
            THEN
               v_errorhint := 'Ruimte toevoegen voor persoon/RIN: ' || prin;

               -- Noot: de srtruimte 1 moet bestaan
               INSERT INTO alg_ruimte
                           (alg_verdieping_key, alg_srtruimte_key, alg_ruimte_nr, alg_ruimte_omschrijving)
                    VALUES (lv_verdieping_key, c_srtruimte_default, c_ruimte_code, c_ruimte_omschr_default)
                 RETURNING alg_ruimte_key
                      INTO lv_ruimte_key;
         END;

         -- lv_ruimte_key bekend
         BEGIN
            SELECT prs_werkplek_key
              INTO lv_werkplek_key
              FROM prs_werkplek
             WHERE prs_alg_ruimte_key = lv_ruimte_key
               AND prs_werkplek_volgnr = c_werkplek_volgnr_default;
         -- Altijd werkplek met deze notatie!
         EXCEPTION
            WHEN NO_DATA_FOUND
            THEN
               v_errorhint := 'Werkplek toevoegen voor persoon/RIN: ' || prin;

               -- WEL/NIET VIRTUEEL?
               INSERT INTO prs_werkplek
                           (prs_werkplek_volgnr, prs_werkplek_omschrijving, prs_alg_ruimte_key, prs_werkplek_virtueel)
                    VALUES (c_werkplek_volgnr_default, c_prs_werkplek_omschrijving, lv_ruimte_key, 0)
                 RETURNING prs_werkplek_key
                      INTO lv_werkplek_key;
         -- Altijd werkplek met deze notatie!
         END;

         -- lv_werkplek_key bekend
         -- 11-12-2009/MvdH - Unique constraint exception igv. virtuele werkplek? Volgens mij wel, maar niet opgelost!
         INSERT INTO prs_perslidwerkplek
                     (prs_perslid_key, prs_werkplek_key, prs_perslidwerkplek_bezetting)
              VALUES (pkey, lv_werkplek_key, 0);
      END IF;
   END;

   PROCEDURE update_adres
   AS
      CURSOR cadressen
      IS
         SELECT DISTINCT
                substr(bezoekadresplaats || '-' || bezoekadresnaam,1,30) adres_naam
              , substr(bezoekadresnaam || ' ' || bezoekadresnummer,1,35) adres_bezoek_adres
              , substr(bezoekadrespostcode,1,12) adres_bezoek_postcode
              , substr(bezoekadresplaats, 1, 30) adres_bezoek_plaats
           FROM rwsn_imp_idm_pers
          WHERE bezoekadrespostcode IS NOT NULL;

      ladreskey        NUMBER (10);
      l_newcount       NUMBER;
      l_impcount       NUMBER;
      v_errormsg       VARCHAR (200);
      oracle_err_mes   VARCHAR2 (150);
      currentversion   fac_module.fac_module_version%TYPE;
   BEGIN

      FOR rc IN cadressen
      LOOP
          -- Bestaat deze al?
         -- Er is geen key, dus checken we op alle velden
         -- Een update is dus nvt
         BEGIN
            SELECT mld_adres_key
              INTO ladreskey
              FROM mld_adres
             WHERE mld_adres_naam = rc.adres_naam
               AND mld_adres_bezoek_postcode = rc.adres_bezoek_postcode
               AND mld_adres_bezoek_adres = rc.adres_bezoek_adres
               AND mld_adres_bezoek_plaats = rc.adres_bezoek_plaats;
         EXCEPTION
            WHEN NO_DATA_FOUND
            THEN
               ladreskey := -1;
         END;

--         DBMS_OUTPUT.put_line (rc.adres_naam);

         IF ladreskey = -1
         THEN
            INSERT INTO mld_adres
                        (mld_adres_naam,
                         mld_adres_bezoek_adres,
                         mld_adres_bezoek_postcode,
                         mld_adres_bezoek_plaats,
                         mld_adres_afleveradres
                        )
                 VALUES (rc.adres_naam, rc.adres_bezoek_adres, rc.adres_bezoek_postcode, rc.adres_bezoek_plaats, 1);

            fac.imp_writelog (p_import_key, 'I', 'Adres is toegevoegd', rc.adres_naam);
         END IF;
      END LOOP;

      -- Zoek de locatiekey bij het adres op basis van postcode
      -- Als er meerdere locaties matchen pak ik de oudste (=grootste?)
      UPDATE mld_adres
         SET alg_locatie_key =
                            (SELECT MIN (l.alg_locatie_key)
                               FROM alg_locatie l
                              WHERE l.alg_locatie_postcode = mld_adres_bezoek_postcode
                                AND UPPER(SUBSTR(RTRIM(l.alg_locatie_adres), INSTR(RTRIM(l.alg_locatie_adres), ' ', -1))) = UPPER(SUBSTR(mld_adres_bezoek_adres, INSTR(mld_adres_bezoek_adres, ' ', -1)))
                                AND l.alg_locatie_verwijder IS NULL)
       WHERE mld_adres_verwijder IS NULL AND alg_locatie_key IS NULL;
   END;


   PROCEDURE update_dienstverbandguid(p_prs_perslid_key IN NUMBER, p_dienstverbandguid IN VARCHAR2)
   AS
   v_prs_kenmerk_key     NUMBER;
   v_prs_kenmerklink_key NUMBER;
   BEGIN
      BEGIN
         -- check for dienstverbandguid kenmerk
         SELECT prs_kenmerk_key
           INTO v_prs_kenmerk_key
           FROM prs_v_aanwezigkenmerk
          WHERE prs_kenmerk_omschrijving = 'DienstverbandGUID';
      EXCEPTION WHEN NO_DATA_FOUND THEN
         INSERT INTO prs_kenmerk
                ( PRS_KENMERK_NIVEAU
                , PRS_KENMERK_VOLGNR
                , PRS_KENMERK_OMSCHRIJVING
                , PRS_KENMERK_KENMERKTYPE
                , PRS_KENMERK_LENGTE)
         VALUES ( 'P'
                , 10
                , 'DienstverbandGUID'
                , 'C'
                , 49
                )
         RETURNING prs_kenmerk_key
              INTO v_prs_kenmerk_key;
      END;
      BEGIN
         SELECT prs_kenmerklink_key
           INTO v_prs_kenmerklink_key
           FROM prs_kenmerklink
          WHERE prs_kenmerk_key = v_prs_kenmerk_key
            AND prs_link_key = p_prs_perslid_key
            AND prs_kenmerklink_niveau = 'P';
      EXCEPTION WHEN NO_DATA_FOUND THEN
         INSERT INTO PRS_KENMERKLINK
                ( PRS_LINK_KEY
                , PRS_KENMERKLINK_NIVEAU
                , PRS_KENMERK_KEY
                , PRS_KENMERKLINK_WAARDE)
         VALUES ( p_prs_perslid_key
                , 'P'
                , v_prs_kenmerk_key
                , p_dienstverbandguid);
      END;
      UPDATE prs_kenmerklink
         SET prs_kenmerklink_waarde = p_dienstverbandguid
       WHERE prs_kenmerklink_key = v_prs_kenmerklink_key;
   END;



----------------------
----------------------
----------------------
----------------------
----------------------
-- MAIN PROCEDURE
----------------------
----------------------
----------------------
----------------------
----------------------
BEGIN
   SELECT MAX (fac_module_version)
     INTO currentversion
     FROM fac_module;

   fac.imp_writelog (p_import_key,
                     'I',
                     'Facilitor IDM_PERS import version ' || currentversion,
                     '$Revision$'
                    );

--   -- #Import
   SELECT COUNT (*)
     INTO v_perslid_count_imp
     FROM rwsn_imp_idm_pers;

   -- Informatieve logging, zien we gelijk hoe laat het was
   fac.imp_writelog (p_import_key, 'S', 'Aantal ingelezen personen: ' || TO_CHAR (v_perslid_count_imp), '');

   -- #Actieve personen mèt RIN
   SELECT COUNT (*)
     INTO v_perslid_count_fclt
     FROM prs_v_aanwezigperslid p, prs_v_aanwezigkenmerklink kl
    WHERE p.prs_perslid_key = kl.prs_link_key AND kl.prs_kenmerk_key = c_rin_kkey;

   -- Check het aantal regels, stop als onvoldoende (=bestaand maar ongeldig bestand)
   IF v_perslid_count_imp = 0
   THEN
      fac.imp_writelog (p_import_key, 'E', 'Het importbestand is ongeldig. Import afgebroken', '');
      RETURN;
   END IF;

   update_adres ();

   -- Begin met het ontmantelen van vervallen personen
   FOR rec_prs_del IN c_prs_del
   LOOP
      BEGIN
         v_perslid_key := rec_prs_del.prs_perslid_key;
         v_errormsg := 'Verwijderen van persoon NIET gelukt';
         v_errorhint := 'Heeft persoon met key ' || TO_CHAR (v_perslid_key) || ' historie?';

         SELECT   SUM (x.aant)
           INTO   v_count
           FROM   (SELECT   COUNT ( * ) aant
                     FROM   prs_v_verplichting_refcheck pv
                    WHERE   pv.prs_perslid_key = v_perslid_key
                   UNION
                   SELECT   COUNT ( * ) aant
                     FROM   fac_tracking t
                    WHERE   t.prs_perslid_key = v_perslid_key) x;

         IF v_count = 0
         THEN
            -- Persoon heeft geen enkele (actuele of historische) verplichting
            v_errorhint := 'Verwijderen van persoon met key ' || TO_CHAR (v_perslid_key);

            DELETE FROM prs_perslid
                  WHERE prs_perslid_key = v_perslid_key;

            --Via trigger!
            --DELETE FROM prs_kenmerklink
            --      WHERE prs_link_key = v_perslid_key AND prs_kenmerklink_niveau = 'P';

            fac.imp_writelog (p_import_key,
                              'I',
                              'Persoon verwijderd; RIN: ' || rec_prs_del.rin,
                              '');
         ELSE
            -- Controleer of er ACTUELE verplichtingen zijn
            SELECT COUNT (*)
              INTO v_count
              FROM prs_v_verplichting_keys pv
             WHERE pv.prs_perslid_key = v_perslid_key;

            IF v_count > 0
            THEN
               UPDATE prs_perslid
                  SET prs_perslid_naam = SUBSTR ('INACTIEF:' || prs_perslid_naam, 1, 30),
                      prs_perslid_oslogin = NULL
                WHERE prs_perslid_key = v_perslid_key AND prs_perslid_naam NOT LIKE 'INACTIEF:%';

               fac.imp_writelog (p_import_key,
                                 'I',
                                 'Persoon INACTIEF; RIN: ' || rec_prs_del.rin,
                                 '');
            ELSE
               -- Er zijn geen actieve verplichtingen, wel historische
               BEGIN
                  UPDATE prs_perslid
                     SET prs_perslid_verwijder = SYSDATE
                   WHERE prs_perslid_key = v_perslid_key;

                  fac.imp_writelog (p_import_key,
                                    'I',
                                    'Persoon verwijderd; RIN: ' || rec_prs_del.rin,
                                    '');
               EXCEPTION
                  WHEN OTHERS
                  THEN
                     -- Kennelijk heeft persoon toch ernstige verplichtingen
                     v_errorhint :=
                           'Persoon heeft nog (max. '
                        || TO_CHAR (v_count)
                        || ') verplichtingen; RIN: '
                        || rec_prs_del.rin;
                     fac.imp_writelog (p_import_key, 'I', v_errormsg, v_errorhint);
               END;
            END IF;
         END IF;
      EXCEPTION
         WHEN OTHERS
         THEN
            oracle_err_num := SQLCODE;
            oracle_err_mes := SUBSTR (SQLERRM, 1, 200);
            v_errormsg := 'Delete exception ' || oracle_err_mes;
            fac.imp_writelog (p_import_key, 'E', v_errormsg, v_errorhint);
      END;
   END LOOP;

   COMMIT;

   -- Ga verder met het toevoegen of bijwerken
   FOR rec_prs_upd IN c_prs_upd
   LOOP
      BEGIN
         -- Init
         v_update := TRUE;                     -- wordt PER RECORD false bij funest gebrek aan vervulde randvoorwaarden
         v_afdeling_key := 0;
         v_srtperslid_key := 0;
         v_perslid_key := 0;
         v_errormsg := 'Fout bij bepalen randvoorwaarden';

         -- *** Controle verplichte gegevens + ophalen extra informatie ***
         -- Controle: RIN
         IF rec_prs_upd.rin IS NULL
         THEN
            v_errorhint := 'Persoon heeft geen RIN; achternaam: ' || rec_prs_upd.prs_perslid_naam;
            fac.imp_writelog (p_import_key, 'W', v_errormsg, v_errorhint);
            v_update := FALSE;
         END IF;

         -- Controle: PRS_PERSLID_NAAM
         IF v_update AND rec_prs_upd.prs_perslid_naam IS NULL
         THEN
            v_errorhint := 'Persoon heeft geen achternaam; RIN: ' || rec_prs_upd.rin;
            fac.imp_writelog (p_import_key, 'W', v_errormsg, v_errorhint);
            v_update := FALSE;
         END IF;

         -- Controle: Persoon reactiveren of is er al een actieve persoon met dezelfde RIN?
         IF v_update AND rec_prs_upd.prs_perslid_verwijder IS NOT NULL
         THEN
            v_errorhint :=
               'Bepalen reactivatie persoon/RIN: ' || rec_prs_upd.rin;

            -- Is er al een actieve persoon met dezelfde RIN?
            SELECT   COUNT (p.prs_perslid_key)
              INTO   v_prs_key_cnt
              FROM   prs_v_aanwezigperslid p, prs_v_aanwezigkenmerklink kl
             WHERE       p.prs_perslid_key = kl.prs_link_key
                     AND kl.prs_kenmerk_key = c_rin_kkey
                     AND kl.prs_kenmerklink_waarde LIKE rec_prs_upd.rin
                     AND p.prs_perslid_key != rec_prs_upd.prs_perslid_key;

            IF v_prs_key_cnt > 0
            THEN
               -- Waarde(n) gevonden, dus is er al een actieve persoon met dezelfde RIN!
               -- => Geen update
               v_update := FALSE;
            ELSE
               -- Kennelijk is er geen actieve persoon met dezelfde RIN!
               -- => Wel update (prs_perslid_verwijder op NULL zetten)
               fac.imp_writelog (
                  p_import_key,
                  'I',
                  'Persoon reactiveren; RIN: ' || rec_prs_upd.rin,
                  ''
               );
            END IF;
         END IF;

         -- Controle: PRS_AFDELING_NAAM
         v_errorhint := 'De afdeling kan niet bepaald worden ' || rec_prs_upd.prs_afdeling_naam;

         IF v_update
         THEN
            BEGIN
               -- Bepaal de afdelingskey; afdelingen worden met een andere import beheerd
               SELECT prs_afdeling_key
                 INTO v_afdeling_key
                 FROM prs_afdeling
                WHERE prs_afdeling_naam = rec_prs_upd.prs_afdeling_naam AND prs_afdeling_verwijder IS NULL;
            EXCEPTION
               WHEN NO_DATA_FOUND
               THEN
                  v_update := FALSE;
                  v_errorhint :=
                        'Afdeling '
                     || rec_prs_upd.prs_afdeling_naam
                     || ' bestaat niet; persoon/RIN: '
                     || rec_prs_upd.rin;
                  -- Kennelijk is de afdeling niet gevonden
                  fac.imp_writelog (p_import_key, 'W', v_errormsg, v_errorhint);
               WHEN OTHERS
               THEN
                  v_update := FALSE;
                  v_errorhint := 'Kan Afdeling ' || rec_prs_upd.prs_afdeling_naam || ' niet eenduidig bepalen?!';
                  fac.imp_writelog (p_import_key, 'W', v_errormsg, v_errorhint);
            END;
         END IF;

         v_errorhint := 'Bepaling functie';

         -- Controle: PRS_SRTPERSLID_OMSCHRIJVING
         IF v_update
         THEN
            BEGIN
               v_srtperslid_omschr := rec_prs_upd.prs_srtperslid_omschrijving;

               -- Bepaal de key van de functie
               SELECT prs_srtperslid_key
                 INTO v_srtperslid_key
                 FROM prs_srtperslid
                WHERE prs_srtperslid_upper = UPPER (v_srtperslid_omschr) AND prs_srtperslid_verwijder IS NULL;
            EXCEPTION
               WHEN NO_DATA_FOUND
               THEN
                  fac.imp_writelog (p_import_key,
                                    'I',
                                    'Functie ' || v_srtperslid_omschr || ' toegevoegd',
                                    v_errorhint
                                   );

                  -- Functie bestaat kennelijk niet, maak 'm maar aan
                  INSERT INTO prs_srtperslid
                              (prs_srtperslid_omschrijving)
                       VALUES (v_srtperslid_omschr);

                  -- Wat is de key van deze nieuwe geworden?
                  SELECT prs_srtperslid_key
                    INTO v_srtperslid_key
                    FROM prs_srtperslid
                   WHERE prs_srtperslid_omschrijving = v_srtperslid_omschr AND prs_srtperslid_verwijder IS NULL;
               WHEN OTHERS
               THEN
                  v_errorhint :=
                        'Functie '
                     || v_srtperslid_omschr
                     || '  kan niet bepaald worden; persoon/RIN: '
                     || rec_prs_upd.rin;
                  v_update := FALSE;
            END;
         END IF;

         IF rec_prs_upd.partnernaam IS NULL THEN
            -- als de partnernaam niet gevuld is dan kunnen we deze ook niet gebruiken.
            lnaampresentatie := rec_prs_upd.prs_perslid_naam;
            ltussenvoegselpres := rec_prs_upd.prs_perslid_tussenvoegsel;
         ELSE
           -- Bepaal de te gebruiken achternaamformattering
           CASE LPAD (rec_prs_upd.aanduidingnaamgebruik, 1, '0')
              WHEN '0'
              THEN
                 BEGIN
                    -- code 0 = [aanhef, titel, voorletters,] voorvoegsels, achternaam
                    -- Opgem. naam  Mevr. T. de Haan
                    lnaampresentatie := rec_prs_upd.prs_perslid_naam;
                    ltussenvoegselpres := rec_prs_upd.prs_perslid_tussenvoegsel;
                 END;
              WHEN '1'
              THEN
                 BEGIN
                    --Code 1 = [aanhef, titel, voorletters,] 2e voorvoegsels, 2e naam(partnernaam) voorvoegsels, achternaam
                    --Opgem. naam  Mevr. T. Bronsgeest-de Haan
                    lnaampresentatie :=
                          rec_prs_upd.partnernaam
                       || '-'
                       || rec_prs_upd.prs_perslid_tussenvoegsel
                       || ' '
                       || rec_prs_upd.prs_perslid_naam;
                    ltussenvoegselpres := rec_prs_upd.partnertussenvoegsel;
                 END;
              WHEN '2'
              THEN
                 BEGIN
                    --Code 2 = [aanhef, titel, voorletters,] voorvoegsels, achternaam, 2e voorvoegsels, 2e naam(partnernaam)
                    --Opgem. naam  Mevr. T. de Haan-Bronsgeest
                    lnaampresentatie :=
                          rec_prs_upd.prs_perslid_naam
                       || '-'
                       || rec_prs_upd.partnertussenvoegsel
                       || ' '
                       || rec_prs_upd.partnernaam;
                    ltussenvoegselpres := rec_prs_upd.prs_perslid_tussenvoegsel;
                 END;
              WHEN '3'
              THEN
                 BEGIN
                    --code 3 = [aanhef, titel, voorletters,] 2e voorvoegsels, 2e naam(partnernaam)
                    --Opgem. naam  Mevr. T. Bronsgeest
                    lnaampresentatie := rec_prs_upd.partnernaam;
                    ltussenvoegselpres := rec_prs_upd.partnertussenvoegsel;
                 END;
              ELSE
                 BEGIN
                    -- code 0 = [aanhef, titel, voorletters,] voorvoegsels, achternaam
                    -- Opgem. naam  Mevr. T. de Haan
                    lnaampresentatie := rec_prs_upd.prs_perslid_naam;
                    ltussenvoegselpres := rec_prs_upd.prs_perslid_tussenvoegsel;
                    fac.imp_writelog (p_import_key,
                                      'W',
                                         'Ongedefinieerd naamformattering (AanduidingNaamGebruik) '
                                      || rec_prs_upd.aanduidingnaamgebruik,
                                      'Default (0) wordt gehanteerd.'
                                     );
                 END;
           END CASE;
         END IF;
         lnaampresentatie := substrb (lnaampresentatie,1,30);

         v_errorhint := 'E-mail';
         lemail := handle_email (rec_prs_upd.email);
         v_errorhint := 'Aanmeldnaam';
         handle_login (rec_prs_upd.loginnaam, rec_prs_upd.prs_perslid_key, llogin1, llogin2);

         -- *** Daadwerkelijk insert/update prs_perslid ***
         IF v_update
         THEN
            BEGIN
               IF rec_prs_upd.prs_perslid_key IS NULL
               THEN
                  v_errormsg := 'Persoon kan niet worden toegevoegd';

                  INSERT INTO prs_perslid
                              (prs_perslid_naam,
                               prs_perslid_tussenvoegsel,
                               prs_perslid_voorletters,
                               prs_perslid_voornaam,
                               prs_perslid_telefoonnr,
                               prs_perslid_authenticatie,
                               prs_perslid_nr,
                               prs_perslid_titel,
                               prs_srtperslid_key,
                               prs_afdeling_key,
                               prs_perslid_oslogin,
                               prs_perslid_oslogin2,
                               prs_perslid_mobiel,
                               prs_perslid_email,
                               prs_perslid_ingangsdatum,
                               prs_perslid_einddatum,
                               fac_profiel_key
                              )
                       VALUES (lnaampresentatie,
                               ltussenvoegselpres,
                               rec_prs_upd.prs_perslid_voorletters,
                               rec_prs_upd.prs_perslid_voornaam,
                               rec_prs_upd.prs_perslid_telefoonnr,
                               rec_prs_upd.personeelsnummer,
                               rec_prs_upd.dienstverbandid,
                               rec_prs_upd.prs_perslid_titel,
                               v_srtperslid_key,
                               v_afdeling_key,
                               llogin1,
                               llogin2,
                               rec_prs_upd.mobielnummer,
                               lemail,
                               rec_prs_upd.begindatum,
                               rec_prs_upd.einddatum,
                               c_default_profiel_key
                              )
                    RETURNING prs_perslid_key
                         INTO v_perslid_key;

                  v_errormsg := 'Fout bij toevoegen RIN';

                  INSERT INTO prs_kenmerklink (prs_link_key,
                                               prs_kenmerklink_niveau,
                                               prs_kenmerk_key,
                                               prs_kenmerklink_waarde)
                    VALUES   (v_perslid_key,
                              'P',
                              c_rin_kkey,
                              rec_prs_upd.rin);

                  fac.imp_writelog (p_import_key,
                                    'I',
                                    'Nieuw persoon toegevoegd',
                                       'Naam/RIN: '
                                    || ltussenvoegselpres || ' ' || lnaampresentatie
                                    || '/'
                                    || rec_prs_upd.rin
                                   );
               ELSE
                  v_errormsg := 'Persoon kan niet worden gewijzigd';

                  UPDATE prs_perslid
                     SET prs_perslid_naam = lnaampresentatie,
                         prs_perslid_tussenvoegsel = ltussenvoegselpres,
                         prs_perslid_voorletters = rec_prs_upd.prs_perslid_voorletters,
                         prs_perslid_voornaam = NVL (rec_prs_upd.prs_perslid_voornaam, prs_perslid_voornaam),
                         prs_perslid_telefoonnr = rec_prs_upd.prs_perslid_telefoonnr,
                         prs_perslid_titel = rec_prs_upd.prs_perslid_titel,
                         prs_srtperslid_key = v_srtperslid_key,
                         prs_afdeling_key = v_afdeling_key,
                         prs_perslid_verwijder = NULL,
                         prs_perslid_oslogin = llogin1,
                         prs_perslid_oslogin2 = COALESCE (prs_perslid_oslogin2, llogin2), -- RWSN#21033!
                         prs_perslid_mobiel = rec_prs_upd.mobielnummer,
                         prs_perslid_email = lemail,
                         prs_perslid_ingangsdatum = rec_prs_upd.begindatum,
                         prs_perslid_einddatum = rec_prs_upd.einddatum,
                         prs_perslid_nr = rec_prs_upd.dienstverbandid
                   WHERE prs_perslid_key = rec_prs_upd.prs_perslid_key
                     AND (   prs_perslid_naam <> lnaampresentatie
                          OR NVL (prs_perslid_tussenvoegsel, '-') <> NVL (ltussenvoegselpres, '-')
                          OR NVL (prs_perslid_voorletters, '-') <> NVL (rec_prs_upd.prs_perslid_voorletters, '-')
                          OR NVL (prs_perslid_voornaam, '-') <> NVL (rec_prs_upd.prs_perslid_voornaam, '-')
                          OR NVL (prs_perslid_telefoonnr, '-') <> NVL (rec_prs_upd.prs_perslid_telefoonnr, '-')
                          OR NVL (prs_perslid_titel, '-') <> NVL (rec_prs_upd.prs_perslid_titel, '-')
                          OR prs_srtperslid_key <> v_srtperslid_key
                          OR prs_afdeling_key <> v_afdeling_key
                          OR NVL (prs_perslid_oslogin, '-') <> NVL (llogin1, '-')
                          OR (prs_perslid_oslogin2 IS NULL AND llogin2 IS NOT NULL)       -- RWSN#21033!
                          OR NVL (prs_perslid_oslogin2, '-') <> NVL (llogin2, '-')
                          OR NVL (prs_perslid_mobiel, '-') <> NVL (rec_prs_upd.mobielnummer, '-')
                          OR NVL (prs_perslid_email, '-') <> NVL (lemail, '-')
                          OR NVL (prs_perslid_ingangsdatum, to_date('01012000', 'ddmmyyyy')) <> NVL (rec_prs_upd.begindatum, to_date('01012000', 'ddmmyyyy'))
                          OR NVL (prs_perslid_einddatum, to_date('01012000', 'ddmmyyyy')) <> NVL (rec_prs_upd.einddatum, to_date('01012000', 'ddmmyyyy'))
                          OR NVL (prs_perslid_nr, '-') <> NVL (rec_prs_upd.dienstverbandid, '-')
                          OR rec_prs_upd.prs_perslid_verwijder IS NOT NULL
                         );

                  v_perslid_key := rec_prs_upd.prs_perslid_key;
               END IF;
            EXCEPTION
               WHEN OTHERS
               THEN
                  oracle_err_num := SQLCODE;
                  oracle_err_mes := SUBSTR (SQLERRM, 1, 100);
                  v_errormsg := v_errormsg || ' - ' || oracle_err_mes;
                  v_errorhint := 'Persoon/RIN: ' || rec_prs_upd.rin;
                  v_update := FALSE;
                  fac.imp_writelog (p_import_key, 'W', v_errormsg, v_errorhint);
            END;
         END IF;

         -- v_perslid_key is nu zeker bekend; zoniet, dan is v_update dus FALSE
         -- en gaan we niet verder aanpassen/aanmaken
         IF v_perslid_key <> 0
         THEN
            -- RWSN#24870: Per RWSN49 vervallen.
            -- ----------------------------------------------------------
            -- DID-stuff: autorisatie van personen op basis van dienst!!!
            -- En, ALLEEN als persoon een login heeft (niet altijd zo)!!!
            -- ----------------------------------------------------------
            -- RWSN#24870-einde!

            v_errorhint := 'Update dienstverbandguid persoon/RIN: ' || rec_prs_upd.rin;
            update_dienstverbandguid(v_perslid_key, rec_prs_upd.dienstverbandguid);

            v_errorhint := 'Locatiebepaling persoon/RIN: ' || rec_prs_upd.rin;

            IF rec_prs_upd.bezoekadrespostcode IS NOT NULL
            THEN
               v_newgebouwkey := getgebouwkey (rec_prs_upd.bezoekadrespostcode, rec_prs_upd.bezoekadresnummer);
               handle_location (v_perslid_key, v_newgebouwkey, rec_prs_upd.rin);
            END IF;

            v_buffercount := v_buffercount + 1;
            IF v_buffercount >= c_commitbuffer
            THEN
               COMMIT;
               v_buffercount := 0;
            END IF;
         END IF;
      EXCEPTION
         WHEN OTHERS
         THEN
            oracle_err_num := SQLCODE;
            oracle_err_mes := SUBSTR (SQLERRM, 1, 100);
            v_errormsg := 'Local exception ' || oracle_err_mes;
            fac.imp_writelog (p_import_key, 'W', v_errormsg, v_errorhint);
      END;
   END LOOP;

   SELECT   COUNT ( * )
     INTO   v_perslid_newcount_fclt
     FROM   prs_v_aanwezigperslid p, prs_v_aanwezigkenmerklink kl
    WHERE   p.prs_perslid_key = kl.prs_link_key
            AND kl.prs_kenmerk_key = c_rin_kkey;

   fac.imp_writelog (
      p_import_key,
      'S',
      'Aantal actieve personen met RIN vooraf: '
      || TO_CHAR (v_perslid_count_fclt)
      || ' nu: '
      || TO_CHAR (v_perslid_newcount_fclt),
      '');

   SELECT   COUNT ( * )
     INTO   v_perslid_newcount_fclt                                -- misbruik
     FROM   prs_v_aanwezigperslid p
    WHERE   NOT EXISTS
               (SELECT   1
                  FROM   prs_v_aanwezigkenmerklink
                 WHERE   prs_link_key = p.prs_perslid_key
                         AND prs_kenmerk_key = c_rin_kkey);

   fac.imp_writelog (
      p_import_key,
      'S',
      'Aantal actieve personen zonder RIN (nu): '
      || TO_CHAR (v_perslid_newcount_fclt),
      '');
EXCEPTION
   WHEN OTHERS
   THEN
      oracle_err_num := SQLCODE;
      oracle_err_mes := SUBSTR (SQLERRM, 1, 100);
      v_errormsg := 'Global exception ' || oracle_err_mes;
      fac.imp_writelog (p_import_key, 'E', v_errormsg, v_errorhint);
END;
/

BEGIN adm.systrackscript('$Workfile: rwsn52.sql $', '$Revision$', 0); END;
/
BEGIN fac.registercustversion('RWSN', 52); END;
/
COMMIT;
spool off
