#ifdef INS
/*
 * $Revision$
 * $Id$
 */

#include    "ins\inssql.h"
#include    "alg\algsql.h"

CREATE_TRIGGER(ins_t_ins_srtdiscipline_B_IU)
BEFORE INSERT OR UPDATE ON ins_srtdiscipline
FOR EACH ROW
BEGIN
    UPDATE_PRIMARY_KEY(ins_srtdiscipline_key,ins_s_ins_srtdiscipline_key);
END;
/

AUDIT_BEGIN(ins_tab_discipline)
AUDIT_VALUE_K(ins_tab_discipline, ins_discipline_key, ins_discipline_omschrijving)
AUDIT_VALUE_K(ins_tab_discipline, ins_discipline_key, ins_discipline_volgnr)
AUDIT_VALUE_K(ins_tab_discipline, ins_discipline_key, prs_kostensoort_key)
AUDIT_VALUE_K(ins_tab_discipline, ins_discipline_key, ins_discipline_kpnverplicht)
AUDIT_VALUE_K(ins_tab_discipline, ins_discipline_key, ins_discipline_email)
AUDIT_VALUE_K(ins_tab_discipline, ins_discipline_key, ins_discipline_ktopercentage)
AUDIT_VALUE_K(ins_tab_discipline, ins_discipline_key, ins_discipline_ktodrempel)
AUDIT_VALUE_K(ins_tab_discipline, ins_discipline_key, ins_discipline_verwijder)
AUDIT_END()

CREATE_TRIGGER(ins_t_ins_discipline_B_IU)
BEFORE INSERT OR UPDATE ON ins_tab_discipline
FOR EACH ROW
BEGIN
    UPDATE_PRIMARY_KEY(ins_discipline_key,ins_s_ins_discipline_key);
    UPDATE_UPPER(ins_discipline_code,ins_discipline_code,ins_tab_discipline);
   IF (    :new.ins_discipline_verwijder IS NOT NULL
       AND:old.ins_discipline_verwijder IS NULL
       AND:new.ins_discipline_module = 'MLD')
   THEN
      DECLARE
         dummy CHAR;
      BEGIN
         SELECT   'x'
           INTO   dummy
           FROM   mld_melding m, mld_stdmelding stdm
          WHERE   (stdm.mld_ins_discipline_key = :new.ins_discipline_key
                   OR m.mld_ins_discipline_key = :new.ins_discipline_key)
            AND   m.mld_stdmelding_key = stdm.mld_stdmelding_key
            AND   m.mld_melding_status IN (0,2,3,4,7);
         raise_application_error (-20000, 'ins_m999 Vakgroep heeft nog open meldingen');
      EXCEPTION
         WHEN NO_DATA_FOUND
         THEN
            NULL;
         WHEN TOO_MANY_ROWS
         THEN
            raise_application_error (-20000, 'ins_m999 Vakgroep heeft nog open meldingen');
      END;
   END IF;

   IF (    :new.ins_discipline_verwijder IS NOT NULL
       AND:old.ins_discipline_verwijder IS NULL
       AND:new.ins_discipline_module = 'BES')
   THEN
      DECLARE
         dummy CHAR;
      BEGIN
         SELECT   'x'
           INTO   dummy
           FROM   bes_bestelopdr_item boi,
                  bes_bestelling_item bbi,
                  bes_srtdeel isd,
                  bes_srtgroep isg,
                  bes_bestelopdr bo
          WHERE       boi.bes_bestelopdr_item_key = bbi.bes_bestelopdr_item_key
                  AND boi.bes_bestelopdr_key = bo.bes_bestelopdr_key
                  AND bbi.bes_srtdeel_key = isd.bes_srtdeel_key
                  AND isd.bes_srtgroep_key = isg.bes_srtgroep_key
                  AND isg.ins_discipline_key = :new.ins_discipline_key
                  AND bo.bes_bestelopdr_status IN (2, 3, 4, 5);

         raise_application_error (-20000, 'ins_m999 Catalogus heeft nog open bestelopdrachten');
      EXCEPTION
         WHEN NO_DATA_FOUND
         THEN
            NULL;
         WHEN TOO_MANY_ROWS
         THEN
            raise_application_error (-20000, 'ins_m999 Catalogus heeft nog open bestelopdrachten');
      END;
   END IF;

   IF (    :new.ins_discipline_verwijder IS NOT NULL
       AND:old.ins_discipline_verwijder IS NULL
       AND:new.ins_discipline_module = 'CNT')
   THEN
      DECLARE
         dummy CHAR;
      BEGIN
         SELECT   'x'
           INTO   dummy
           FROM   cnt_contract c
          WHERE   c.ins_discipline_key = :new.ins_discipline_key
            AND   c.cnt_contract_status = 0
            AND   c.cnt_contract_verwijder IS NULL
            AND   c.cnt_contract_looptijd_tot >= SYSDATE;
         raise_application_error (-20000, 'ins_m999 Contractsoort heeft nog actieve contracten');
      EXCEPTION
         WHEN NO_DATA_FOUND
         THEN
            NULL;
         WHEN TOO_MANY_ROWS
         THEN
            raise_application_error (-20000, 'ins_m999 Contractsoort heeft nog actieve contracten');
      END;
   END IF;

   IF (    :new.ins_discipline_verwijder IS NOT NULL
       AND :old.ins_discipline_verwijder IS NULL
       AND :new.ins_discipline_module = 'RES')
   THEN
       BEGIN DELETE FROM res_activiteitdiscipline WHERE res_activiteitdiscipline.res_discipline_key = :new.ins_discipline_key; END;
   END IF;


    SET_VERWIJDER_CHILDREN(ins_srtgroep, ins_discipline_key, ins_discipline_verwijder,
        ins_srtgroep_verwijder,ins_tab_discipline);
    SET_VERWIJDER_CHILDREN(bes_srtgroep, ins_discipline_key, ins_discipline_verwijder,
        bes_srtgroep_verwijder,ins_tab_discipline);
    IF (:new.ins_discipline_verwijder IS NOT NULL AND :old.ins_discipline_verwijder IS NULL) THEN DELETE_CHILDREN(fac_groeprechten,ins_discipline_key); END IF;
    UPDATE_AANMAAKDATUM(ins_tab_discipline, ins_discipline_aanmaak);
END;
/

CREATE_TRIGGER(ins_t_ins_srtgroep_B_IU)
BEFORE INSERT OR UPDATE ON ins_srtgroep
FOR EACH ROW
BEGIN
    UPDATE_PRIMARY_KEY(ins_srtgroep_key,ins_s_ins_srtgroep_key);
    UPDATE_UPPER(ins_srtgroep_omschrijving,ins_srtgroep_upper,ins_srtgroep);
    SET_VERWIJDER_CHILDREN(ins_srtdeel, ins_srtgroep_key, ins_srtgroep_verwijder,
        ins_srtdeel_verwijder,ins_srtgroep);
    UPDATE_AANMAAKDATUM(ins_srtgroep, ins_srtgroep_aanmaak);
END;
/

CREATE_TRIGGER(ins_t_ins_srtdeel_B_IU)
BEFORE INSERT OR UPDATE ON ins_srtdeel
FOR EACH ROW
BEGIN

    UPDATE_PRIMARY_KEY(ins_srtdeel_key,ins_s_ins_srtinst_keys);
    UPDATE_UPPER(ins_srtdeel_omschrijving,ins_srtdeel_upper,ins_srtdeel);
    UPDATE_UPPER(ins_srtdeel_code,ins_srtdeel_code_upper,ins_srtdeel);
    UPDATE_UPPER(ins_srtdeel_cadlayer, ins_srtdeel_cadlayer,ins_srtdeel);
    -- 16/04/1998 AH #1593, Speciale CHECK_NOG_REFERENCE, maakt geen gebruik van AANWEZIG-views.
    INS_CHECK_NOG_REFERENCES(ins_srtdeel,ins_srtdeel_verwijder,ins_deel, ins_deel_verwijder
                            ,ins_srtdeel_key,'ins_m013');
//<CNT>
    IF :new.ins_srtdeel_verwijder IS NOT NULL THEN
      DECLARE
        dummy CHAR;
      BEGIN
        SELECT 'x'
        INTO   dummy
        FROM   cnt_v_aanwezigcontract_object
        WHERE  cnt_v_aanwezigcontract_object.cnt_ins_srtdeel_key = :old.ins_srtdeel_key;
        APPLICATION_ERROR_GOTO(-20000,'cnt_m029');
      EXCEPTION
        WHEN NO_DATA_FOUND THEN NULL;
        WHEN TOO_MANY_ROWS THEN APPLICATION_ERROR_GOTO(-20000,'cnt_m029');
      END;
    END IF;
//</CNT>
    UPDATE_AANMAAKDATUM(ins_srtdeel, ins_srtdeel_aanmaak);
    SET_VERWIJDER_CHILDREN(ins_srtdeel_compositie, ins_srtdeel_key, ins_srtdeel_verwijder
                          ,ins_srtdeel_comp_verwijder,ins_srtdeel);
 END;
/

CREATE_TRIGGER(ins_t_ins_deel_B_I)
BEFORE INSERT ON ins_deel
FOR EACH ROW
BEGIN
   UPDATE_PRIMARY_KEY(ins_deel_key,ins_s_ins_inst_keys);
END;
/

CREATE_TRIGGER(ins_t_ins_deel_B_IU)
BEFORE INSERT OR UPDATE ON ins_deel
FOR EACH ROW
DECLARE
  Dummy1 BOOLEAN;
BEGIN
   UPDATE_UPPER(ins_deel_omschrijving,ins_deel_upper,ins_deel);
   IF :new.ins_deel_verwijder IS NOT NULL AND :old.ins_deel_verwijder IS NULL THEN
     DECLARE
       dummy CHAR;
     BEGIN
       SELECT 'x'
       INTO   dummy
       FROM   cnt_v_aanwezigcontract_object, cnt_v_aanwezigcontract
       WHERE  cnt_v_aanwezigcontract_object.cnt_contract_key = cnt_v_aanwezigcontract.cnt_contract_key
          AND cnt_v_aanwezigcontract_object.cnt_ins_deel_key = :old.ins_deel_key
          AND cnt_v_aanwezigcontract.cnt_contract_looptijd_tot > sysdate;
       raise_application_error(-20000, 'cnt_m030');
     EXCEPTION
       WHEN NO_DATA_FOUND THEN NULL;
       WHEN TOO_MANY_ROWS THEN raise_application_error(-20000, 'cnt_m030');
     END;

     IF :new.ins_deel_parent_key IS NULL
     THEN
       DECLARE
         Dummy BOOLEAN;
       BEGIN
          Dummy := fac.remember_SavePrimaryKeyAndDate('INS_DEEL_VERWIJDER', :new.ins_deel_key, :old.ins_deel_verwijder);
       END;
     END IF;

     DECLARE
        dummy  CHAR;
        lCount NUMBER;
      BEGIN
      -- Een deel mag niet verwijderd worden als er nog openstaande meldingen zijn...
      SELECT COUNT(*)
      INTO   lCount
        FROM mld_v_aanwezigmelding_object O, mld_melding M
       WHERE O.ins_deel_key = :old.ins_deel_key
         AND O.mld_melding_key = M.mld_melding_key
         AND M.mld_melding_status IN (0,2,3,4,7);
 	  IF lCount > 0 THEN
          APPLICATION_ERROR_GOTO(-20000,'ins_m202');
      ELSE
        Dummy1 := fac.remember_SavePrimaryKey('INS_DEEL_ONTKOPPEL', :new.ins_deel_key);
      END IF;

     UPDATE res_deel SET res_deel_verwijder = :new.ins_deel_verwijder
     WHERE res_ins_deel_key=:new.ins_deel_key
     AND res_deel_verwijder IS NULL;
     END;
   END IF;

   -- Vul het veld INS_DISCIPLINE van het huidige deel.
   IF :old.ins_srtdeel_key IS NULL
   OR :old.ins_srtdeel_key <> :new.ins_srtdeel_key
   OR :old.ins_discipline_key IS NULL
   THEN
      BEGIN
         SELECT INS_SG.ins_discipline_key
         INTO   :new.ins_discipline_key
         FROM   ins_srtdeel        INS_SD
         ,      ins_srtgroep       INS_SG
         WHERE  INS_SD.ins_srtdeel_key    = :new.ins_srtdeel_key
         AND    INS_SD.ins_srtgroep_key   = INS_SG.ins_srtgroep_key;
      EXCEPTION
         WHEN NO_DATA_FOUND
         THEN :new.ins_discipline_key := NULL;
      END;
   END IF;
   -- Zoek de (redundante) alg_locatie_key erbij indien verplaatst.
   -- Echter NIET voor persoonsgebonden objecten !!!
   -- Soms kan de querie niet worden uitgevoerd omdat bovenliggende tabellen in bewerking zijn
   -- dan: ORA - 04091: table X is mutating, trigger/function may not see it
   -- dan blijft de locatie ongewijzigd (dikke kans)
   IF :old.ins_alg_ruimte_key  IS NULL
   OR :old.ins_alg_ruimte_key  <> :new.ins_alg_ruimte_key
   OR :new.ins_alg_locatie_key IS NULL
   THEN
     IF :new.ins_alg_ruimte_type not IN ('A','C','P')
     THEN
       BEGIN
         SELECT alg_locatie_key
           INTO :new.ins_alg_locatie_key
           FROM ins_v_alg_overzicht
          WHERE alg_onroerendgoed_keys = :new.ins_alg_ruimte_key
            AND alg_onroerendgoed_type = :new.ins_alg_ruimte_type;
       EXCEPTION
         WHEN NO_DATA_FOUND
         THEN :new.ins_alg_locatie_key := NULL;
         WHEN OTHERS
         THEN NULL;
       END;
     END IF;
   END IF;
   /* Bij INS_DEEL moet INS_ALG_RUIMTE_KEY ingevuld zijn
    * en wel met ruimte, werkplek of terreinsector, afdeling of persoon
    * Daarvoor moet ook het INS_ALG_RUIMTE_TYPE veld goed ingevuld zijn
    * (met 'W', 'R' of 'T' of 'A' of 'P').
    * Dit geldt als INS_ALG_RUIMTE_KEY veranderd is of als er een
    * nieuw record geinsert wordt.
    */
   IF :new.ins_deel_verwijder IS NULL
     AND (:old.ins_alg_ruimte_key <> :new.ins_alg_ruimte_key OR :old.ins_alg_ruimte_key IS NULL)
   THEN
      IF    :new.ins_alg_ruimte_type = 'W'
      THEN
         CHECK_KEY_REFERENCE(prs_werkplek     , prs_werkplek_key     , :new.ins_alg_ruimte_key, 'ins_m174');
      ELSIF :new.ins_alg_ruimte_type = 'R'
      THEN
         CHECK_KEY_REFERENCE(alg_v_aanwezigruimte       , alg_ruimte_key       , :new.ins_alg_ruimte_key, 'ins_m092');
      ELSIF :new.ins_alg_ruimte_type = 'T'
      THEN
         CHECK_KEY_REFERENCE(alg_v_aanwezigterreinsector, alg_terreinsector_key, :new.ins_alg_ruimte_key, 'ins_m095');
      ELSIF :new.ins_alg_ruimte_type = 'A'
      THEN
         CHECK_KEY_REFERENCE(prs_v_aanwezigafdeling     , prs_afdeling_key     , :new.ins_alg_ruimte_key, 'ins_m194');
      ELSIF :new.ins_alg_ruimte_type = 'C'
      THEN
         CHECK_KEY_REFERENCE(prs_contactpersoon      , prs_contactpersoon_key      , :new.ins_alg_ruimte_key, 'ins_m195');
      ELSIF :new.ins_alg_ruimte_type = 'P'
      THEN
         CHECK_KEY_REFERENCE(prs_v_aanwezigperslid      , prs_perslid_key      , :new.ins_alg_ruimte_key, 'ins_m195');
      ELSE
         APPLICATION_ERROR_GOTO(-20000, 'ins_m84');
      END IF;
      DECLARE
         Dummy BOOLEAN;
      BEGIN
         -- Alleen bestaande delen hebben mogelijk te verplaatsen onderdelen.
         IF  :old.ins_deel_aanmaak IS NOT NULL
         AND :new.ins_deel_parent_key IS NULL
         THEN
            Dummy := fac.remember_SavePrimaryKey('INS_DEEL_CASCADE', :new.ins_deel_key);
         END IF;
      END;
   END IF;
   UPDATE_AANMAAKDATUM(ins_deel, ins_deel_aanmaak);
END;
/

CREATE_TRIGGER(ins_t_ins_deel_A_U)
AFTER UPDATE ON ins_deel
FOR EACH ROW
DECLARE
  new_date DATE;
  prev_state   ins_deel_state_history.ins_deel_state%TYPE;
BEGIN
   IF (:old.ins_deel_state  IS NULL AND :new.ins_deel_state IS NOT NULL)
    OR (:new.ins_deel_state  <> :old.ins_deel_state)
   THEN
     BEGIN
       new_date := COALESCE (:new.ins_deel_statedate, SYSDATE); -- voorkom dat de update *net* een seconde later kan zijn
       INSERT INTO ins_deel_state_history (ins_deel_key, ins_deel_state, ins_deel_statedate)
       VALUES (:new.ins_deel_key, :new.ins_deel_state, COALESCE(:new.ins_deel_statedate, new_date));
     EXCEPTION
         WHEN DUP_VAL_ON_INDEX
         THEN
            SELECT ins_deel_state
              INTO prev_state
              FROM ins_deel_state_history
             WHERE ins_deel_state_history_key =
                      (SELECT MAX (ins_deel_state_history_key)
                         FROM ins_deel_state_history
                        WHERE ins_deel_key = :new.ins_deel_key
                              AND ins_deel_statedate < new_date);

            IF (prev_state = :new.ins_deel_state)
            THEN
               DELETE ins_deel_state_history
                WHERE ins_deel_key = :new.ins_deel_key
                      AND ins_deel_statedate = new_date;
            ELSE -- kan alleen bij tri-stste statussen gebeuren
               UPDATE ins_deel_state_history
                  SET ins_deel_state = :new.ins_deel_state
                WHERE ins_deel_key = :new.ins_deel_key
                      AND ins_deel_statedate = new_date;
            END IF;
      END;
   END IF;
END;
/

CREATE_TRIGGER(ins_t_ins_deel_S_A_IU)
AFTER UPDATE ON ins_deel
BEGIN
   DECLARE
      IndexNr    NUMBER;
      PrimaryKey NUMBER(10);
      Dummy      BOOLEAN;
      lNested    NUMBER;
      lCount     NUMBER;
      deletemode DATE;
      old_datum_of_deel DATE;
   BEGIN
      -- We controleren of we zijn aangeroepen vanuit onszelf. Ook al hebben we daarbij
      -- geen keys aan fac_selectie toegevoegd, die van het hoogste niveau staan er, en
      -- die moeten we niet weer vanaf nummer 1 gaan behandelen, anders zitten we echt
      -- in een oneindige loop.
      -- We krijgen hier geen mee, omdat we geen onderdelen van onderdelen kennen.
      lNested := fac.remember_GetPrimaryKey('INS_TRIGGER_BUSY', 1);
      IF lNested IS NULL
      THEN
         IndexNr    := 1;
         PrimaryKey := fac.remember_GetPrimaryKey('INS_DEEL_VERWIJDER', IndexNr);
         old_datum_of_deel := fac.remember_GetDate('INS_DEEL_VERWIJDER', PrimaryKey);

         WHILE PrimaryKey IS NOT NULL
         LOOP
            Dummy := fac.remember_SavePrimaryKey('INS_TRIGGER_BUSY', 1);
            /* Jammer maar helaas, vanwege syntaxredenen moeten we weten of we met UNDO te maken hebben
            /* Als parent is verwijderd, dan is deletemode gevuld met zijn datum */
            /* Als parent terug wordt gehaald, dan is delete-mode gevuld met NULL ( betekent FALSE) */
            SELECT ins_deel_verwijder
            INTO deletemode
            FROM ins_deel
            WHERE ins_deel_key = PrimaryKey;


            IF deletemode IS NULL /* Het deel wordt terug gehaald (UNDO) */
            THEN
            	UPDATE ins_deel
            	SET    ins_deel_verwijder = NULL /* Bijbehorende onderdelen ook terughalen */
            	WHERE  ins_deel.ins_deel_parent_key = PrimaryKey
            	AND    ins_deel.ins_deel_verwijder = old_datum_of_deel;
            ELSE
            	/* Het deel wordt (of beter: is) verwijderd */
                --
                -- Als dit object als kenmerk in een ander object wordt gebruikt
                -- mag dit object niet worden verwijderd.
                --
                DECLARE
                  v_referentie  VARCHAR2(100);
                BEGIN
                  BEGIN
                    SELECT D.ins_deel_omschrijving
                    INTO   v_referentie
                    FROM   ins_deel D
                    ,      ins_kenmerkdeel KD
                    ,      ins_kenmerk     K
                    ,      ins_srtkenmerk  SK
                    ,      fac_kenmerkdomein RS
                    WHERE  D.ins_deel_verwijder IS NULL
                    AND    RS.fac_kenmerkdomein_kolomnaam = 'INS_DEEL_KEY'
                    AND    RS.fac_kenmerkdomein_key       = SK.fac_kenmerkdomein_key
                    AND    SK.ins_srtkenmerk_key          = K.ins_srtkenmerk_key
                    AND    K.ins_kenmerk_key              = KD.ins_kenmerk_key
                    AND    KD.ins_deel_key                = D.ins_deel_key
                    AND    KD.ins_kenmerkdeel_verwijder  IS NULL
                    AND    KD.ins_kenmerkdeel_waarde     IN (SELECT to_char(PrimaryKey)
                                                             FROM   dual
                                                             UNION
                                                             SELECT to_char(ins_deel_key)
                                                             FROM   ins_deel
                                                             WHERE  ins_deel_parent_key = PrimaryKey);
                  EXCEPTION
                    WHEN NO_DATA_FOUND THEN v_referentie := null;
                    WHEN TOO_MANY_ROWS THEN v_referentie := 'X';
                  END;
                  --
                  IF v_referentie IS NOT NULL
                  THEN
                    -- Dit object of een van zijn onderdelen wordt dus als referentie in een ander object gebruikt.
                    -- Draai het verwijderen terug.
                    UPDATE ins_deel
                    SET    ins_deel_verwijder = null
                    WHERE  ins_deel_key = PrimaryKey;
                    APPLICATION_ERROR_GOTO(-20000,'ins_m202');
                  ELSE
                    -- Dit object of een van zijn onderdelen wordt niet als referentie naar een ander object gebruikt.
                    -- De onderdelen mogen nu ook verwijderd worden.
                    UPDATE ins_deel
                    SET    ins_deel_verwijder = deletemode /* Alle AANWEZIGE onderdelen verwijderen */
                    WHERE  ins_deel.ins_deel_parent_key = PrimaryKey
                    AND    ins_deel.ins_deel_verwijder IS NULL;
                  END IF;
                END;
            END IF;

            Dummy := fac.remember_ResetSelectie('INS_TRIGGER_BUSY');
            IndexNr    := IndexNr + 1;
            PrimaryKey := fac.remember_GetPrimaryKey('INS_DEEL_VERWIJDER', IndexNr);
            old_datum_of_deel := fac.remember_GetDate('INS_DEEL_VERWIJDER', PrimaryKey);

         END LOOP;
         Dummy := fac.remember_ResetSelectie('INS_DEEL_VERWIJDER');
         IndexNr    := 1;
         PrimaryKey := fac.remember_GetPrimaryKey('INS_DEEL_CASCADE', IndexNr);
         WHILE PrimaryKey IS NOT NULL
         LOOP
            -- Om weer te voorkomen dat de BEFORE STATEMENT trigger onnodig vuurt, controleren
            -- we eerst of het statement wel nodig is, d.i. of er onderdelen zijn die nog
            -- verplaatst moeten worden.
            SELECT COUNT(*)
            INTO   lCount
            FROM   ins_deel
            WHERE  ins_deel.ins_deel_parent_key = PrimaryKey
            AND    ins_deel.ins_deel_verwijder IS NULL;

            IF lCount > 0
            THEN
               Dummy := fac.remember_SavePrimaryKey('INS_TRIGGER_BUSY', 1);
               UPDATE ins_deel
               SET   (ins_alg_ruimte_key
               ,      ins_alg_ruimte_type
               ,      ins_alg_locatie_key) = (SELECT ins_alg_ruimte_key
                                              ,      ins_alg_ruimte_type
                                              ,      ins_alg_locatie_key
                                              FROM   ins_deel
                                              WHERE  ins_deel_key = PrimaryKey)
               WHERE  ins_deel.ins_deel_parent_key = PrimaryKey
               AND    ins_deel.ins_deel_verwijder IS NULL;

               Dummy := fac.remember_ResetSelectie('INS_TRIGGER_BUSY');
            END IF;
            IndexNr    := IndexNr + 1;
            PrimaryKey := fac.remember_GetPrimaryKey('INS_DEEL_CASCADE', IndexNr);
         END LOOP;
         Dummy := fac.remember_ResetSelectie('INS_DEEL_CASCADE');
      ELSE
         NULL;
      END IF; -- lNested
   END;
   -- Add statements that need execution even when nested here:
   --
   -- Attentie: Alle koppelingen met delen uit de selectie worden verwijderd. Doordat deze
   -- selectie tijdens deze transactie groter kan worden door de bijbehorende onderdelen, wordt
   -- mogelijkerwijs vaker ins.delete_deelkoppeling() aangeroepen dan strikt nodig is (de reeds
   -- aanwezige keys blijven oon staan). Dit is niet echt een probleem in de huidige context, maar
   -- kan dat worden als die functie veel tijd kost ook al is er niks te doen.
   DECLARE
      IndexNr     NUMBER;
      PrimaryKey  NUMBER(10);
      Dummy       BOOLEAN;
   BEGIN
      IndexNr    := 1;
      PrimaryKey := fac.remember_GetPrimaryKey('INS_DEEL_ONTKOPPEL', IndexNr);
      WHILE PrimaryKey IS NOT NULL
      LOOP
         Dummy := ins.delete_deelkoppeling(PrimaryKey);
         IndexNr    := IndexNr + 1;
         PrimaryKey := fac.remember_GetPrimaryKey('INS_DEEL_ONTKOPPEL', IndexNr);
      END LOOP;
      Dummy := fac.remember_ResetSelectie('INS_DEEL_ONTKOPPEL');
    END;
END;
/

CREATE_TRIGGER(ins_t_ins_deel_state_hist_B_I)
BEFORE INSERT ON ins_deel_state_history
FOR EACH ROW
BEGIN
    UPDATE_PRIMARY_KEY(ins_deel_state_history_key,ins_s_ins_deel_state_hist_key);
END;
/


CREATE_TRIGGER(ins_t_ins_import_B_IU)
BEFORE INSERT OR UPDATE ON ins_import
FOR EACH ROW
BEGIN
    UPDATE_PRIMARY_KEY(ins_import_key,ins_s_ins_import_key);
    UPDATE_AANMAAKDATUM(ins_import, ins_import_aanmaak);
END;
/* dummy commentaar omdat anders de volgende / wegvalt? */
/

CREATE_TRIGGER(ins_t_ins_srtkenmerk_b_iu)
BEFORE INSERT OR UPDATE ON ins_srtkenmerk
FOR EACH ROW
BEGIN
    UPDATE_PRIMARY_KEY(ins_srtkenmerk_key, ins_s_ins_srtkenmerk_key);
    UPDATE_UPPER(ins_srtkenmerk_omschrijving, ins_srtkenmerk_upper,ins_srtkenmerk);
    UPDATE_AANMAAKDATUM(ins_srtkenmerk, ins_srtkenmerk_aanmaak);
    IF (:new.ins_srtkenmerk_verwijder IS NOT NULL AND :old.ins_srtkenmerk_verwijder IS NULL AND
      :new.ins_srtkenmerk_systeem = 1)
    THEN
      APPLICATION_ERROR(-20003, 'INS_M156');
    END IF;

    IF :new.ins_srtkenmerk_kenmerktype IN ('C', 'N', 'B') AND :new.ins_srtkenmerk_lengte IS NULL
    THEN
       APPLICATION_ERROR(-20000, 'INS_C_INS_SRTKENMERK_LENGTE');
    END IF;
    -- Numeriek mag niet te lang zijn (numeric overflow)
    IF :new.ins_srtkenmerk_kenmerktype IN ('N', 'B') AND :new.ins_srtkenmerk_lengte > 20
    THEN
       :new.ins_srtkenmerk_lengte := 20;
    END IF;

    IF :new.ins_srtkenmerk_kenmerktype IN ('N', 'B') AND :old.ins_srtkenmerk_key IS NOT NULL
    THEN
      IF :old.ins_srtkenmerk_nmin <> :new.ins_srtkenmerk_nmin OR
        (:old.ins_srtkenmerk_nmin IS NULL AND :new.ins_srtkenmerk_nmin IS NOT NULL)
      THEN
        DECLARE
          Dummy CHAR;
        BEGIN
          SELECT 'X'
          INTO Dummy
          FROM ins_kenmerkdeel
          WHERE FAC.SAFE_TO_NUMBER(ins_kenmerkdeel_waarde) < :new.ins_srtkenmerk_nmin
            AND ins_kenmerk_key IN
            (SELECT ins_kenmerk_key
               FROM ins_kenmerk
                WHERE ins_srtkenmerk_key = :old.ins_srtkenmerk_key);
           raise_application_error(-20000, 'INS_C_INS_SRTKENMERK_MIN');
        EXCEPTION
          WHEN NO_DATA_FOUND
          THEN NULL;
          WHEN TOO_MANY_ROWS
            THEN raise_application_error(-20000, 'INS_C_INS_SRTKENMERK_MIN');
        END;
      END IF;
      IF :old.ins_srtkenmerk_nmax <> :new.ins_srtkenmerk_nmax OR
        (:old.ins_srtkenmerk_nmax IS NULL AND :new.ins_srtkenmerk_nmax IS NOT NULL)
      THEN
        DECLARE
          Dummy CHAR;
        BEGIN
          SELECT 'X'
          INTO Dummy
          FROM ins_kenmerkdeel
          WHERE FAC.SAFE_TO_NUMBER(ins_kenmerkdeel_waarde) > :new.ins_srtkenmerk_nmax
            AND ins_kenmerk_key IN
            (SELECT ins_kenmerk_key
               FROM ins_kenmerk
                WHERE ins_srtkenmerk_key = :old.ins_srtkenmerk_key);
           raise_application_error(-20000, 'INS_C_INS_SRTKENMERK_MAX');
        EXCEPTION
          WHEN NO_DATA_FOUND
          THEN NULL;
          WHEN TOO_MANY_ROWS
            THEN raise_application_error(-20000, 'INS_C_INS_SRTKENMERK_MAX');
        END;
      END IF;
    END IF;
END;
/

CREATE_TRIGGER(ins_t_ins_kenmerk_b_iu)
BEFORE INSERT OR UPDATE ON ins_kenmerk
FOR EACH ROW
BEGIN
     -- FSN#13902: we tolereren het achteraf verplicht maken
    UPDATE_PRIMARY_KEY(ins_kenmerk_key, ins_s_ins_kenmerk_key);
    UPDATE_AANMAAKDATUM(ins_kenmerk, ins_kenmerk_aanmaak);
END;
/

CREATE_TRIGGER(ins_t_ins_kenmerkdeel_b_iu)
BEFORE INSERT OR UPDATE ON ins_kenmerkdeel
FOR EACH ROW
BEGIN
/* Controleer eerst of de ingevulde waarde goed is. */
IF :new.ins_kenmerkdeel_waarde <> :old.ins_kenmerkdeel_waarde
OR :old.ins_kenmerkdeel_waarde IS NULL
OR :new.ins_kenmerkdeel_waarde IS NULL
THEN
DECLARE
   SrtKenmerkOmschr   ins_srtkenmerk.ins_srtkenmerk_omschrijving%TYPE;
   SrtKenmerkType     ins_srtkenmerk.ins_srtkenmerk_kenmerktype%TYPE;
   SrtKenmerkLengte   ins_srtkenmerk.ins_srtkenmerk_lengte%TYPE;
   SrtKenmerkDec      ins_srtkenmerk.ins_srtkenmerk_dec%TYPE;
   SrtKenmerkNMin     ins_srtkenmerk.ins_srtkenmerk_nmin%TYPE;
   SrtKenmerkNMax     ins_srtkenmerk.ins_srtkenmerk_nmax%TYPE;
   KenmerkVerplicht   ins_kenmerk.ins_kenmerk_verplicht%TYPE;
   NumberWaarde       NUMBER(25,5);
   FormatMask         VARCHAR2(60);
   KenmerkDeelWaarde  ins_kenmerkdeel.ins_kenmerkdeel_waarde%TYPE;
BEGIN
   KenmerkDeelWaarde := :new.ins_kenmerkdeel_waarde;

   SELECT INS_SK.ins_srtkenmerk_omschrijving,
          INS_SK.ins_srtkenmerk_kenmerktype,
          INS_SK.ins_srtkenmerk_lengte,
          INS_SK.ins_srtkenmerk_dec,
          INS_SK.ins_srtkenmerk_nmin,
          INS_SK.ins_srtkenmerk_nmax,
          INS_K.ins_kenmerk_verplicht
   INTO  SrtKenmerkOmschr,
         SrtKenmerkType,
         SrtKenmerkLengte,
         SrtKenmerkDec,
         SrtKenmerkNMin,
         SrtKenmerkNMax,
         KenmerkVerplicht
   FROM ins_srtkenmerk INS_SK, ins_kenmerk INS_K
   WHERE INS_SK.ins_srtkenmerk_key = INS_K.ins_srtkenmerk_key
     AND INS_K.ins_kenmerk_key = :new.ins_kenmerk_key;

   /* Controleer eerst of het verplichte veld ingevuld is */
   IF KenmerkVerplicht IS NOT NULL AND KenmerkDeelWaarde IS NULL
   THEN
      APPLICATION_ERROR_GOTO(-20004, 'ins_m149,'||SrtKenmerkOmschr);
   /* Kijk welk KenmerkType gebruikt wordt.
    * Aan de hand daarvan moet een controle uitgevoerd worden.
    */
   ELSIF SrtKenmerkType = 'C' /* Char */
   THEN
      /* Controleer of de lengte te groot of goed is */
      IF LENGTH(KenmerkDeelWaarde) > SrtKenmerkLengte
      THEN
         APPLICATION_ERROR_GOTO(-20004, 'ins_m143,'||SrtKenmerkOmschr||','||TO_CHAR(SrtKenmerkLengte));
      END IF;
   ELSIF SrtKenmerkType IN ('N', 'B') /* Number */
   THEN
     /* Controleer of er een numerieke waarde ingevuld is */
     IF SrtKenmerkDec IS NULL OR SrtKenmerkDec = 0
     THEN
        FormatMask := RPAD('9', SrtKenmerkLengte, '9');
     ELSE
        FormatMask := RPAD('9', SrtKenmerkLengte - SrtKenmerkDec, '9')||
                           'D'||RPAD('9', SrtKenmerkDec, '9');
     END IF;
     /* Controleer of er een numerieke waarde ingevuld is */
     BEGIN
      NumberWaarde := TO_NUMBER(KenmerkDeelWaarde);
     EXCEPTION
      WHEN OTHERS
      THEN FormatMask := REPLACE(FormatMask, '9', '#');
           FormatMask := REPLACE(FormatMask, '0', '#');
           FormatMask := REPLACE(FormatMask, 'D', '.');
           APPLICATION_ERROR_GOTO(-20004,'ins_m146,'||SrtKenmerkOmschr||','||FormatMask);
     END;
      /* Controleer of de waarde binnen NMin en NMax ligt */
      IF (SrtKenmerkNMin IS NOT NULL
      AND NumberWaarde < SrtKenmerkNMin)
      OR (SrtKenmerkNMax IS NOT NULL
      AND NumberWaarde > SrtKenmerkNMax)
      THEN
         APPLICATION_ERROR_GOTO(-20004, 'ins_m145,'||SrtKenmerkOmschr||','||
                                                TO_CHAR(SrtKenmerkNMin)||','||
                                                TO_CHAR(SrtKenmerkNMax));
      ELSE
          /*  Controleer of de waarde aan het formaat voldoet */
          KenmerkDeelWaarde := LTRIM(NUMBER_TO_CHAR(NumberWaarde, FormatMask));
          IF INSTR2(KenmerkDeelWaarde, '#') <> 0
          THEN
            FormatMask := REPLACE(FormatMask, '9', '#');
            FormatMask := REPLACE(FormatMask, '0', '#');
            FormatMask := REPLACE(FormatMask, 'D', '.');
            APPLICATION_ERROR_GOTO(-20004,'ins_m146,'||SrtKenmerkOmschr||','||FormatMask);
          END IF;
      END IF;
      /* Zet de geconverteerde waarde terug */
      :new.ins_kenmerkdeel_waarde := KenmerkDeelWaarde;
   ELSIF SrtKenmerkType = 'D' /* Datum */
   THEN
      KenmerkDeelWaarde := DATE_TO_CHAR(_TO_DATE2(KenmerkDeelWaarde,'DD-MM-YY'), 'DD-MM-YYYY');
      /* Zet de geconverteerde waarde terug */
      :new.ins_kenmerkdeel_waarde := KenmerkDeelWaarde;
   END IF;
END;
   UPDATE_PRIMARY_KEY(ins_kenmerkdeel_key, ins_s_ins_kenmerkdeel_key);
END IF;

END;
/
CREATE_TRIGGER(ins_t_ins_kmdeelsrtcontr_b_iu)
BEFORE INSERT OR UPDATE ON ins_kmdeelsrtcontr
FOR EACH ROW
BEGIN
/* Controleer eerst of de ingevulde waarde goed is. */
IF :new.ins_kmdeelsrtcontr_waarde <> :old.ins_kmdeelsrtcontr_waarde
OR :old.ins_kmdeelsrtcontr_waarde IS NULL
OR :new.ins_kmdeelsrtcontr_waarde IS NULL
THEN
DECLARE
   SrtKenmerkOmschr   ins_srtkenmerk.ins_srtkenmerk_omschrijving%TYPE;
   SrtKenmerkType     ins_srtkenmerk.ins_srtkenmerk_kenmerktype%TYPE;
   SrtKenmerkLengte   ins_srtkenmerk.ins_srtkenmerk_lengte%TYPE;
   SrtKenmerkDec      ins_srtkenmerk.ins_srtkenmerk_dec%TYPE;
   SrtKenmerkNMin     ins_srtkenmerk.ins_srtkenmerk_nmin%TYPE;
   SrtKenmerkNMax     ins_srtkenmerk.ins_srtkenmerk_nmax%TYPE;
   KenmerkVerplicht   ins_kenmerk.ins_kenmerk_verplicht%TYPE;
   NumberWaarde       NUMBER(25,5);
   FormatMask         VARCHAR2(60);
   KenmerkControleWaarde  ins_kmdeelsrtcontr.ins_kmdeelsrtcontr_waarde%TYPE;
BEGIN
   KenmerkControleWaarde := :new.ins_kmdeelsrtcontr_waarde;

   SELECT INS_SK.ins_srtkenmerk_omschrijving,
          INS_SK.ins_srtkenmerk_kenmerktype,
          INS_SK.ins_srtkenmerk_lengte,
          INS_SK.ins_srtkenmerk_dec,
          INS_SK.ins_srtkenmerk_nmin,
          INS_SK.ins_srtkenmerk_nmax,
          INS_K.ins_kenmerk_verplicht
   INTO  SrtKenmerkOmschr,
         SrtKenmerkType,
         SrtKenmerkLengte,
         SrtKenmerkDec,
         SrtKenmerkNMin,
         SrtKenmerkNMax,
         KenmerkVerplicht
   FROM ins_srtkenmerk INS_SK, ins_kenmerk INS_K
   WHERE INS_SK.ins_srtkenmerk_key = INS_K.ins_srtkenmerk_key
     AND INS_K.ins_kenmerk_key = :new.ins_kenmerk_key;

   /* Controleer eerst of het verplichte veld ingevuld is */
   IF KenmerkVerplicht IS NOT NULL AND KenmerkControleWaarde IS NULL
   THEN
      APPLICATION_ERROR_GOTO(-20004, 'ins_m149,'||SrtKenmerkOmschr);
   /* Kijk welk KenmerkType gebruikt wordt.
    * Aan de hand daarvan moet een controle uitgevoerd worden.
    */
   ELSIF SrtKenmerkType = 'C' /* Char */
   THEN
      /* Controleer of de lengte te groot of goed is */
      IF LENGTH(KenmerkControleWaarde) > SrtKenmerkLengte
      THEN
         APPLICATION_ERROR_GOTO(-20004, 'ins_m143,'||SrtKenmerkOmschr||','||TO_CHAR(SrtKenmerkLengte));
      END IF;
   ELSIF SrtKenmerkType IN ('N', 'B') /* Number */
   THEN
     /* Controleer of er een numerieke waarde ingevuld is */
     IF SrtKenmerkDec IS NULL OR SrtKenmerkDec = 0
     THEN
        FormatMask := RPAD('9', SrtKenmerkLengte, '9');
     ELSE
        FormatMask := RPAD('9', SrtKenmerkLengte - SrtKenmerkDec, '9')||
                           'D'||RPAD('9', SrtKenmerkDec, '9');
     END IF;
     /* Controleer of er een numerieke waarde ingevuld is */
     BEGIN
      NumberWaarde := TO_NUMBER(KenmerkControleWaarde);
     EXCEPTION
      WHEN OTHERS
      THEN FormatMask := REPLACE(FormatMask, '9', '#');
           FormatMask := REPLACE(FormatMask, '0', '#');
           FormatMask := REPLACE(FormatMask, 'D', '.');
           APPLICATION_ERROR_GOTO(-20004,'ins_m146,'||SrtKenmerkOmschr||','||FormatMask);
     END;
      /* Controleer of de waarde binnen NMin en NMax ligt */
      IF (SrtKenmerkNMin IS NOT NULL
      AND NumberWaarde < SrtKenmerkNMin)
      OR (SrtKenmerkNMax IS NOT NULL
      AND NumberWaarde > SrtKenmerkNMax)
      THEN
         APPLICATION_ERROR_GOTO(-20004, 'ins_m145,'||SrtKenmerkOmschr||','||
                                                TO_CHAR(SrtKenmerkNMin)||','||
                                                TO_CHAR(SrtKenmerkNMax));
      ELSE
          /*  Controleer of de waarde aan het formaat voldoet */
          KenmerkControleWaarde := LTRIM(NUMBER_TO_CHAR(NumberWaarde, FormatMask));
          IF INSTR2(KenmerkControleWaarde, '#') <> 0
          THEN
            FormatMask := REPLACE(FormatMask, '9', '#');
            FormatMask := REPLACE(FormatMask, '0', '#');
            FormatMask := REPLACE(FormatMask, 'D', '.');
            APPLICATION_ERROR_GOTO(-20004,'ins_m146,'||SrtKenmerkOmschr||','||FormatMask);
          END IF;
      END IF;
      /* Zet de geconverteerde waarde terug */
      :new.ins_kmdeelsrtcontr_waarde := KenmerkControleWaarde;
   ELSIF SrtKenmerkType = 'D' /* Datum */
   THEN
      KenmerkControleWaarde := DATE_TO_CHAR(_TO_DATE2(KenmerkControleWaarde,'DD-MM-YY'), 'DD-MM-YYYY');
      /* Zet de geconverteerde waarde terug */
      :new.ins_kmdeelsrtcontr_waarde := KenmerkControleWaarde;
   END IF;
END;
   UPDATE_PRIMARY_KEY(ins_kmdeelsrtcontr_key, ins_s_ins_kmdeelsrtcontr_key);
END IF;

END;
/

CREATE_TRIGGER(ins_t_ins_deelkoppeling_b_iu)
BEFORE INSERT OR UPDATE ON ins_deelkoppeling
FOR EACH ROW
BEGIN
   UPDATE_PRIMARY_KEY(ins_deelkoppeling_key, ins_s_ins_deelkoppeling_key);
   UPDATE_AANMAAKDATUM(ins_deelkoppeling, ins_deelkoppeling_aanmaak);
END;
/

CREATE_TRIGGER(ins_t_ins_compositie_b_iu)
BEFORE INSERT OR UPDATE ON ins_compositie
FOR EACH ROW
BEGIN
   UPDATE_PRIMARY_KEY(ins_compositie_key, ins_s_ins_compositie_key);
   UPDATE_UPPER(ins_compositie_naam,ins_compositie_upper,ins_compositie);
   UPDATE_AANMAAKDATUM(ins_compositie, ins_compositie_aanmaak);
   SET_VERWIJDER_CHILDREN(ins_srtdeel_compositie, ins_compositie_key, ins_compositie_verwijder,
       ins_srtdeel_comp_verwijder,ins_compositie);
END;
/

CREATE_TRIGGER(ins_t_ins_srtdeel_comp_b_iu)
BEFORE INSERT OR UPDATE ON ins_srtdeel_compositie
FOR EACH ROW
BEGIN
   UPDATE_PRIMARY_KEY(ins_srtdeel_comp_key, ins_s_ins_srtdeel_comp_key);
   UPDATE_AANMAAKDATUM(ins_srtdeel_compositie, ins_srtdeel_comp_aanmaak);
END;
/

CREATE_TRIGGER(ins_srtdeel_srtdeel_B_IU)
BEFORE INSERT  OR UPDATE ON ins_srtdeel_srtdeel
FOR EACH ROW
BEGIN
  UPDATE_PRIMARY_KEY(ins_srtdeel_srtdeel_key, ins_s_ins_srtdeel_srtdeel_key);
END;
/

CREATE_TRIGGER(ins_t_scenario_B_IU)
BEFORE INSERT  OR UPDATE ON ins_scenario
FOR EACH ROW
BEGIN
  UPDATE_PRIMARY_KEY(ins_scenario_key, ins_s_ins_scenario_key);
END;
/

CREATE_TRIGGER(ins_t_scenario_B_D)
BEFORE DELETE ON ins_scenario
FOR EACH ROW
BEGIN
  IF :old.ins_scenario_key = 1 THEN
    raise_application_error (-20000, 'Cannot delete actual scenario');
  END IF;
END;
/

CREATE_TRIGGER(ins_t_srtcontrole_B_IU)
BEFORE INSERT  OR UPDATE ON ins_srtcontrole
FOR EACH ROW
BEGIN
  UPDATE_PRIMARY_KEY(ins_srtcontrole_key, ins_s_ins_srtcontrole_key);
END;
/

CREATE_TRIGGER(ins_t_controlemode_B_IU)
BEFORE INSERT  OR UPDATE ON ins_controlemode
FOR EACH ROW
BEGIN
  UPDATE_PRIMARY_KEY(ins_controlemode_key, ins_s_ins_controlemode_key);
END;
/

CREATE_TRIGGER(ins_t_srtcontroledl_xcp_B_IU)
BEFORE INSERT  OR UPDATE ON ins_srtcontroledl_xcp
FOR EACH ROW
BEGIN
  UPDATE_PRIMARY_KEY(ins_srtcontroledl_xcp_key, ins_s_srtcontroledl_xcp_key);
END;
/

CREATE_TRIGGER(ins_t_deelsrtcontrole_B_IU)
BEFORE INSERT  OR UPDATE ON ins_deelsrtcontrole
FOR EACH ROW
BEGIN
  UPDATE_PRIMARY_KEY(ins_deelsrtcontrole_key, ins_s_ins_deelsrtcontrole_key);
END;
/

AUDIT_BEGIN(ins_disc_params)
AUDIT_VALUE(ins_disc_params, ins_disc_params_autonum)
AUDIT_VALUE(ins_disc_params, ins_disc_params_cadlayers)
AUDIT_VALUE(ins_disc_params, ins_disc_params_type)
AUDIT_END()

CREATE_TRIGGER(ins_t_ins_disc_params_b_iu)
BEFORE INSERT OR UPDATE ON ins_disc_params
FOR EACH ROW
BEGIN
   IF :new.ins_disc_params_key IS NULL THEN SELECT ins_s_ins_disc_params_key.nextval INTO :new.ins_disc_params_key FROM DUAL; END IF;
END;
/

CREATE_TRIGGER(ins_t_ins_deel_note_B_IU)
BEFORE INSERT OR UPDATE ON ins_deel_note
FOR EACH ROW
BEGIN
     UPDATE_PRIMARY_KEY(ins_deel_note_key, ins_s_ins_deel_note_key);
END;
/

REGISTERRUN('$Id$')

#endif
