--
-- $Id$
--
-- Script containing customer specific sql statements for the FACILITOR database

DEFINE thisfile = 'HCAS.SQL'
DEFINE dbuser   = '^HCAS'

SET ECHO ON
SET DEFINE ON
COLUMN fcltlogfile NEW_VALUE fcltlogfile NOPRINT;
WHENEVER SQLERROR EXIT;

SELECT adm.scriptspoolfile ('&dbuser', '&thisfile') AS fcltlogfile FROM DUAL;

WHENEVER SQLERROR CONTINUE;
SPOOL &fcltlogfile
SET DEFINE OFF

------ payload begin ------

----- Personenimport -------------------------------------------------------------------------------

CREATE OR REPLACE PROCEDURE hcas_import_perslid (p_import_key IN NUMBER)
AS
   oracle_err_num   NUMBER;
   oracle_err_mes   VARCHAR2 (200);
   v_errormsg       VARCHAR2 (400);
   v_errorhint      VARCHAR2 (400);
BEGIN
   v_errorhint := 'Generieke update';
   -- de sequence array staat beschreven in PRS_PAC.SRC bij de prs.import_perslid proc
   prs.import_perslid (
      p_import_key,
         '0;0;0;0;0;8;1;2;0;3;'
      || '0;0;0;0;0;0;0;6;0;0;'
      || '5;1;0;0;0;0;4;0;0;0;'
      || '0;0;0;0;0;0;0;0;0;0;'
      || '0;0;0;0;0;0',
      '"SamAccountName";"sn";"GivenName";"Department";"Function";"Mail";"TelephoneNumber";"Location"%');

   COMMIT;
EXCEPTION
   WHEN OTHERS
   THEN
      oracle_err_num := SQLCODE;
      oracle_err_mes := SUBSTR (SQLERRM, 1, 100);
      v_errormsg := 'Error ' || oracle_err_num || '/' || oracle_err_mes;
      fac.imp_writelog (p_import_key,
                        'E',
                        v_errormsg,
                        v_errorhint);
END hcas_import_perslid;
/


CREATE OR REPLACE PROCEDURE hcas_update_perslid (p_import_key IN NUMBER)
IS
   -- Alle personen verwijderen die niet meer in import bestand voorkomen.
   -- Key bij HCAS is SAMAccountName, hieronder de query om alle personen te verwijderen die:
   -- a) niet meer in het importbestand staan, wel in Facilitor, en
   -- b) waarvan de persoon in Facilitor geen alternatieve login heeft (gevuld alt. login van af blijven, dit zijn persleden die handmatig zijn toegevoegd)
   -- c) waarvan de persoon in Facilitor niet begint met een _ in de loginnaam (ook van af blijven)
   CURSOR c_del
   IS
        SELECT p.prs_perslid_key,
               p.prs_perslid_oslogin,
               p.prs_perslid_oslogin2,
               pf.prs_perslid_naam_full
          FROM fac_imp_perslid i, prs_perslid p, prs_v_perslid_fullnames_all pf
         WHERE UPPER (p.prs_perslid_oslogin) = UPPER (i.prs_perslid_oslogin(+))
               AND SUBSTR (p.prs_perslid_oslogin, 1, 1) <> '_'
               AND i.prs_perslid_oslogin IS NULL
               AND p.prs_perslid_verwijder IS NULL
               AND p.prs_perslid_oslogin2 IS NULL
               AND pf.prs_perslid_key = p.prs_perslid_key
      ORDER BY 2;

   oracle_err_num   NUMBER;
   oracle_err_mes   VARCHAR2 (200);
   v_errormsg       VARCHAR2 (400);
   v_count          NUMBER;
BEGIN
   -- generic update

   SELECT COUNT ( * ) INTO v_count FROM fac_imp_perslid;

   UPDATE fac_imp_perslid i
      SET i.prs_perslid_telefoonnr =
             (SELECT p.prs_perslid_telefoonnr
                FROM prs_perslid p
               WHERE p.prs_perslid_verwijder IS NULL
                     AND UPPER (P.PRS_PERSLID_OSLOGIN) =
                           UPPER (I.PRS_PERSLID_OSLOGIN))
    WHERE i.fac_import_key = p_import_key;

   UPDATE fac_imp_perslid i
      SET i.prs_perslid_mobiel =
             (SELECT p.prs_perslid_mobiel
                FROM prs_perslid p
               WHERE p.prs_perslid_verwijder IS NULL
                     AND UPPER (P.PRS_PERSLID_OSLOGIN) =
                           UPPER (I.PRS_PERSLID_OSLOGIN))
    WHERE i.fac_import_key = p_import_key;

   -- Afdelingsomschrijving ingelezen in kenmerk; op basis daarvan de afdelingscode
   -- invullen (verplicht veld afdelingscode tijdelijk gevuld met oslogin).
   UPDATE fac_imp_perslid i
      SET prs_afdeling_naam =
             (SELECT prs_afdeling_naam
                FROM prs_afdeling a
               WHERE prs_afdeling_verwijder IS NULL
                     AND UPPER (a.prs_afdeling_omschrijving) =
                           UPPER (i.prs_kenmerk1));

   -- Onbekende afdelingen bewaren voor logging
   UPDATE fac_imp_perslid
      SET prs_afdeling_naam = SUBSTR (prs_kenmerk1, 1, 15)
    WHERE prs_afdeling_naam IS NULL;

   -- Locatieomschrijving ingelezen; op basis daarvan de juiste vastgoedgegevens
   -- in de juiste kolommen zetten.
   -- Omdat werkplekken alleen worden aangevuld, dit alleen doen voor personen die
   -- nog geen werkplek hebben.
   UPDATE fac_imp_perslid i
      SET
          (alg_locatie_code,
          alg_gebouw_code,
          alg_verdieping_volgnr,
          alg_ruimte_nr
          ) =
             (  SELECT rg.alg_locatie_code,
                       MIN (rg.alg_gebouw_upper),
                       MIN (rg.alg_verdieping_volgnr),
                       rg.alg_ruimte_nr
                  FROM alg_v_ruimte_gegevens rg
                 WHERE i.prs_werkplek_omschrijving =
                          rg.alg_locatie_omschrijving
                       AND rg.alg_ruimte_nr = '_WP'
              GROUP BY rg.alg_locatie_code, rg.alg_ruimte_nr)
    WHERE NOT EXISTS
             (SELECT DISTINCT prs_perslid_oslogin
                FROM prs_perslidwerkplek pw, prs_v_aanwezigperslid ap
               WHERE ap.prs_perslid_key = pw.prs_perslid_key
                     AND ap.prs_perslid_oslogin =
                           UPPER (i.prs_perslid_oslogin));

   -- Tijdelijke gegevens opruimen
   UPDATE fac_imp_perslid i
      SET prs_werkplek_omschrijving = NULL, prs_kenmerk1 = NULL;

   COMMIT;

   -- 'LOGIN' betekent dat op basis van Login wordt gematched.
   -- 'NR' betekent dat op basis van Personeelsnummer wordt gematched.
   -- 'A' betekent altijd alle (andere/overige) werkplekken verwijderen
   prs.update_perslid (p_import_key, 'LOGIN', NULL);

   -- Verwijder personen die niet meer in de import voorkomen.
   FOR rec IN c_del
   LOOP
      BEGIN
         prs.delete_perslid (p_import_key, rec.prs_perslid_key);
      END;
   END LOOP;
EXCEPTION
   WHEN OTHERS
   THEN
      oracle_err_num := SQLCODE;
      oracle_err_mes := SUBSTR (SQLERRM, 1, 100);
      v_errormsg := 'Error ' || oracle_err_num || '/' || oracle_err_mes;
      fac.imp_writelog (p_import_key,
                        'E',
                        v_errormsg,
                        'Importproces personen afgebroken!');
END hcas_update_perslid;
/

----- Export servicenow -------------------------------------------------------------------------------
-- Deze export draait steeds voorafgaand aan put-orders
-- In deze export doen we 3 dingen:
   -- Wanneer er een externnummer bij een opdracht bekend is, maar nog niet bij de melding, dan zetten we deze ook bij de melding (nodig voor aansturing naar Servicenow)
   -- Wanneer de aanvragen een notitie bij de melding heeft gezet, moet deze naar Servicenow gestuurd worden. We zetten hem weer in de orderqueue. 
   -- Ook zetten we de synchronisatietijd bij de melding, zodat eerdere notities niet nogmaals gestuurd worden.
/* Formatted on 6-6-2019 14:13:13 (QP5 v5.136.908.31019) */
CREATE OR REPLACE PROCEDURE hcas_export_servicenow (p_applname   IN VARCHAR2,
                                                    p_applrun    IN VARCHAR2,
                                                    p_filedir    IN VARCHAR2,
                                                    p_filename   IN VARCHAR2)
AS
   oracle_err_num   NUMBER;
   oracle_err_mes   VARCHAR2 (200);
   v_errorhint      VARCHAR2 (100);
   v_locatie_key    NUMBER;
   v_lengte         NUMBER;

   --Onderstaande cursor verzamelt de meldingen die status 'Actie aanvrager' moeten krijgen. Dat is obv het binnenkomende opdrachtkenmerk 'Statusservicenow'.
   CURSOR actie
   IS
        SELECT mld.mld_melding_key
          FROM fac_tracking t,
               mld_opdr o,
               mld_melding mld,
               mld_stdmelding sm
         WHERE     sm.mld_stdmelding_key = mld.mld_stdmelding_key
               AND sm.mld_ins_discipline_key IN (321, 341, 342)
               AND mld.mld_melding_key = o.mld_melding_key
               AND o.mld_opdr_key = t.fac_tracking_refkey
               AND t.fac_srtnotificatie_key = 61                     -- ORDUPD
               AND INSTR (t.fac_tracking_oms,
                          'Statusservicenow: (leeg) --> Pending Customer') > 0
               AND ( (SELECT fac.safe_to_number (
                                sync.mld_kenmerkmelding_waarde)
                        FROM mld_kenmerkmelding sync,
                             mld_kenmerk km,
                             mld_srtkenmerk skm,
                             mld_melding m
                       WHERE     m.mld_melding_key = sync.mld_melding_key
                             AND m.mld_melding_key = mld.mld_melding_key
                             AND km.mld_kenmerk_key = sync.mld_kenmerk_key
                             AND skm.mld_srtkenmerk_key = km.mld_srtkenmerk_key
                             AND skm.mld_srtkenmerk_key = 541) <
                       fac.safe_to_number (
                          TO_CHAR (t.fac_tracking_datum, 'yyyymmddhh24miss'))
                    OR ( (SELECT fac.safe_to_number (
                                    sync.mld_kenmerkmelding_waarde)
                            FROM mld_kenmerkmelding sync,
                                 mld_kenmerk km,
                                 mld_srtkenmerk skm,
                                 mld_melding m
                           WHERE     m.mld_melding_key = sync.mld_melding_key
                                 AND m.mld_melding_key = mld.mld_melding_key
                                 AND km.mld_kenmerk_key = sync.mld_kenmerk_key
                                 AND skm.mld_srtkenmerk_key =
                                       km.mld_srtkenmerk_key
                                 AND skm.mld_srtkenmerk_key = 541) IS NULL))
      GROUP BY mld.mld_melding_key;

   -- Dit haalt het externnummer op van een opdrachtkenmerk indien externnr bij de melding nog leeg is
   CURSOR externnr
   IS
      SELECT DISTINCT
             m.mld_melding_key,
             o.mld_opdr_key,
             ko.mld_kenmerkopdr_waarde AS externnr
        FROM mld_melding m,
             mld_opdr o,
             mld_stdmelding sm,
             mld_kenmerkopdr ko,
             mld_kenmerk km,
             mld_srtkenmerk skm
       WHERE     m.mld_melding_key = o.mld_melding_key
             AND sm.mld_stdmelding_key = m.mld_stdmelding_key
             AND sm.mld_ins_discipline_key IN (321, 341, 342) -- Enkel voor de vakgroepen die met servicenow gekoppeld worden.
             AND m.mld_melding_externnr IS NULL
             AND o.mld_opdr_key = ko.mld_opdr_key
             AND km.mld_kenmerk_key = ko.mld_kenmerk_key
             AND skm.mld_srtkenmerk_key = km.mld_srtkenmerk_key
             AND skm.mld_srtkenmerk_key = 405;       --Kenmerksoort 'Externnr'

   --Onderstaande cursor verzamelt de gegevens om te bepalen welke meldingen nieuwe opmerkingen heeft en die verzonden kunnen worden naar Servicenow
   CURSOR sync
   IS
      SELECT mld_melding_key,
             mld_ins_discipline_key,
             mld_melding_note_aanmaak,
             fac.safe_to_number (
                TO_CHAR (mld_melding_note_aanmaak, 'yyyymmddhh24miss'))
                AS note,
             sync,
             sync_key
        FROM (  SELECT mld_melding_key,
                       mld_ins_discipline_key,
                       MAX (mld_melding_note_aanmaak)
                          AS mld_melding_note_aanmaak,
                       sync,
                       sync_key
                  FROM (  SELECT mld.mld_melding_key,
                                 sm.mld_ins_discipline_key,
                                 mn.mld_melding_note_aanmaak,
                                 (SELECT fac.safe_to_number (
                                            sync.mld_kenmerkmelding_waarde)
                                    FROM mld_kenmerkmelding sync,
                                         mld_kenmerk km,
                                         mld_srtkenmerk skm,
                                         mld_melding m
                                   WHERE m.mld_melding_key = sync.mld_melding_key
                                         AND m.mld_melding_key =
                                               mld.mld_melding_key
                                         AND km.mld_kenmerk_key =
                                               sync.mld_kenmerk_key
                                         AND skm.mld_srtkenmerk_key =
                                               km.mld_srtkenmerk_key
                                         AND skm.mld_srtkenmerk_key = 541) -- Kenmerksoort tbv synchronisatie van opmerkingen naar Servicenow
                                    AS sync,
                                 (SELECT sync.mld_kenmerkmelding_key
                                    FROM mld_kenmerkmelding sync,
                                         mld_kenmerk km,
                                         mld_srtkenmerk skm,
                                         mld_melding m
                                   WHERE m.mld_melding_key = sync.mld_melding_key
                                         AND m.mld_melding_key =
                                               mld.mld_melding_key
                                         AND km.mld_kenmerk_key =
                                               sync.mld_kenmerk_key
                                         AND skm.mld_srtkenmerk_key =
                                               km.mld_srtkenmerk_key
                                         AND skm.mld_srtkenmerk_key = 541) -- Kenmerksoort tbv synchronisatie van opmerkingen naar Servicenow
                                    AS sync_key
                            FROM mld_melding mld,
                                 mld_melding_note mn,
                                 mld_stdmelding sm,
                                 mld_kenmerk km
                           WHERE mn.mld_melding_key = mld.mld_melding_key
                                 AND sm.mld_stdmelding_key =
                                       mld.mld_stdmelding_key
                                 AND km.mld_stdmelding_key =
                                       sm.mld_ins_discipline_key
                                 AND km.mld_srtkenmerk_key = 541
                                 AND sm.mld_ins_discipline_key IN (321, 341, 342) -- Enkel voor de vakgroepen die met servicenow gekoppeld worden.
                                 --       AND mld.mld_melding_key = 73362
                                 AND ( (SELECT fac.safe_to_number (
                                                  sync.mld_kenmerkmelding_waarde)
                                          FROM mld_kenmerkmelding sync,
                                               mld_kenmerk km,
                                               mld_srtkenmerk skm,
                                               mld_melding m
                                         WHERE m.mld_melding_key =
                                                  sync.mld_melding_key
                                               AND m.mld_melding_key =
                                                     mld.mld_melding_key
                                               AND km.mld_kenmerk_key =
                                                     sync.mld_kenmerk_key
                                               AND skm.mld_srtkenmerk_key =
                                                     km.mld_srtkenmerk_key
                                               AND skm.mld_srtkenmerk_key = 541) <
                                         fac.safe_to_number(TO_CHAR (
                                                               mld_melding_note_aanmaak,
                                                               'yyyymmddhh24miss'))
                                      OR ( (SELECT fac.safe_to_number(sync.mld_kenmerkmelding_waarde)
                                              FROM mld_kenmerkmelding sync,
                                                   mld_kenmerk km,
                                                   mld_srtkenmerk skm,
                                                   mld_melding m
                                             WHERE m.mld_melding_key =
                                                      sync.mld_melding_key
                                                   AND m.mld_melding_key =
                                                         mld.mld_melding_key
                                                   AND km.mld_kenmerk_key =
                                                         sync.mld_kenmerk_key
                                                   AND skm.mld_srtkenmerk_key =
                                                         km.mld_srtkenmerk_key
                                                   AND skm.mld_srtkenmerk_key =
                                                         541) IS NULL))
                        ORDER BY mld_melding_key, mld_melding_note_aanmaak ASC)
              GROUP BY mld_melding_key,
                       mld_ins_discipline_key,
                       sync,
                       sync_key);

   --Onderstaande cursor verzamelt de meldingen die een andere locatie hebben dan is doorgegeven vanuit Servicenow.
   CURSOR locatie
   IS
      SELECT m.mld_melding_key,
             o.mld_opdr_key,
             (SELECT alg_onrgoed_key
                FROM alg_onrgoedkenmerk
               WHERE alg_onrgoed_niveau = 'L' AND alg_kenmerk_key = 1300
                     AND ko.mld_kenmerkopdr_waarde =
                           alg_onrgoedkenmerk_waarde)
                AS loc_opdr_key,
             ko.mld_kenmerkopdr_waarde AS locatie_opdracht,
             m.mld_alg_locatie_key,
             m.mld_alg_onroerendgoed_keys,
             (SELECT alg_onrgoedkenmerk_waarde
                FROM alg_onrgoedkenmerk
               WHERE     alg_onrgoed_niveau = 'L'
                     AND alg_kenmerk_key = 1300 --Kenmerk 'Locatie servicenow'
                     AND alg_onrgoed_key = m.mld_alg_locatie_key)
                AS locatie_melding
        FROM mld_melding m,
             mld_opdr o,
             mld_stdmelding sm,
             mld_kenmerkopdr ko,
             mld_kenmerk km,
             mld_srtkenmerk skm
       WHERE     m.mld_melding_key = o.mld_melding_key
             AND sm.mld_stdmelding_key = m.mld_stdmelding_key
             AND sm.mld_ins_discipline_key IN (321, 341, 342) -- Enkel voor de vakgroepen die met servicenow gekoppeld worden.
             AND o.mld_opdr_key = ko.mld_opdr_key
             AND km.mld_kenmerk_key = ko.mld_kenmerk_key
             AND skm.mld_srtkenmerk_key = km.mld_srtkenmerk_key
             AND skm.mld_srtkenmerk_key = 404     --Kenmerksoort 'Locatiecode'
             AND ( (ko.mld_kenmerkopdr_waarde <>
                       (SELECT alg_onrgoedkenmerk_waarde
                          FROM alg_onrgoedkenmerk
                         WHERE     alg_onrgoed_niveau = 'L'
                               AND alg_kenmerk_key = 1300
                               AND alg_onrgoed_key = m.mld_alg_locatie_key)
                    AND m.mld_alg_locatie_key <> 61) -- Wanneer er een onbekende omschrijving is en locatie bij de melding is al hoofdkantoor (61), dan niet in de cursor omdat anders bij iedere putorders de locatie wordt gewijzigd (voorkomt veel tracking)...
                  OR m.mld_alg_locatie_key IS NULL);

   --Onderstaande cursor haalt de meldingen op waar er een short description is bij de opdracht, maar nog niet in de meldingsomschrijving.
   CURSOR descr
   IS
      SELECT DISTINCT
             m.mld_melding_key,
             o.mld_opdr_key,
             ko.mld_kenmerkopdr_waarde AS short_description,
             fac.safe_to_number (LENGTH (ko.mld_kenmerkopdr_waarde))
                AS lengte,
             m.mld_melding_omschrijving
        FROM mld_melding m,
             mld_opdr o,
             mld_stdmelding sm,
             mld_kenmerkopdr ko,
             mld_kenmerk km,
             mld_srtkenmerk skm
       WHERE     m.mld_melding_key = o.mld_melding_key
             AND sm.mld_stdmelding_key = m.mld_stdmelding_key
             AND sm.mld_ins_discipline_key IN (321, 341, 342) -- Enkel voor de vakgroepen die met servicenow gekoppeld worden.
             AND m.mld_melding_onderwerp IS NULL
             AND o.mld_opdr_bedrijfopdr_volgnr = 1 -- Enkel voor de eerste opdracht, normaal ook altijd maar één opdracht per melding.
             AND o.mld_opdr_key = ko.mld_opdr_key
             AND km.mld_kenmerk_key = ko.mld_kenmerk_key
             AND skm.mld_srtkenmerk_key = km.mld_srtkenmerk_key
             AND skm.mld_srtkenmerk_key = 402; --Kenmerksoort 'Short_description'
BEGIN
   v_errorhint := 'init';
   v_lengte := 0;

   -- We zetten de status van de melding nog op 'Actie aanvrager' indien Servicenow na laatste bericht vanuit Facilitor hierom vraag.
   FOR rec IN actie
   LOOP
      BEGIN
         v_errorhint :=
            'Status melding naar Actie aanvrager voor melding '
            || rec.mld_melding_key;

         UPDATE mld_melding
            SET mld_melding_actiecode = 2
          WHERE mld_melding_key = rec.mld_melding_key;
      END;
   END LOOP;

   -- Hier vullen we het externnr bij de melding, zodra deze (als kenmerk) bij de opdracht binnenkomt vanuit Servicenow
   FOR rec IN externnr
   LOOP
      BEGIN
         v_errorhint :=
            'Melding vullen met externnr voor melding '
            || rec.mld_melding_key;

         UPDATE mld_melding
            SET mld_melding_externnr = rec.externnr
          WHERE mld_melding_key = rec.mld_melding_key;
      END;
   END LOOP;

   FOR rec IN sync
   LOOP
      BEGIN
         v_errorhint :=
            'Opdracht opnieuw te verzenden voor melding '
            || rec.mld_melding_key;

         -- Eerst zetten we de opdracht opnieuw klaar om te verzenden
         UPDATE mld_opdr
            SET mld_opdr_teverzenden = 2, mld_opdr_verzonden = NULL
          WHERE mld_melding_key = rec.mld_melding_key;

         v_errorhint :=
            'Syncdatum bijwerken voor melding ' || rec.mld_melding_key;

         -- Daarna hogen we de syncdatum bij de meldingen op met de datum van de laatst ingevoerde notitie
         -- Hiermee komt deze notitie de volgende keer niet meer voor in de cursor.
         CASE
            WHEN rec.sync IS NULL
            THEN
               INSERT INTO mld_kenmerkmelding (mld_melding_key,
                                               mld_kenmerk_key,
                                               mld_kenmerkmelding_waarde)
                   VALUES (rec.mld_melding_key,
                           (SELECT DISTINCT mld_kenmerk_key
                              FROM mld_kenmerk
                             WHERE mld_srtkenmerk_key = 541 -- 541 = Kenmerksoort tbv synchronisatie van opmerkingen naar Servicenow
                                   AND mld_stdmelding_key =
                                         rec.mld_ins_discipline_key),
                           rec.note);

               fac.trackaction ('MLDUPD',
                                rec.mld_melding_key,
                                NULL,
                                NULL,
                                'Sync_ServiceNow: (leeg) --> ' || rec.note);
            ELSE
               UPDATE mld_kenmerkmelding
                  SET mld_kenmerkmelding_waarde = rec.note
                WHERE rec.sync_key = mld_kenmerkmelding_key;

               fac.trackaction (
                  'MLDUPD',
                  rec.mld_melding_key,
                  NULL,
                  NULL,
                  'Sync_ServiceNow: ' || rec.sync || ' --> ' || rec.note);
         END CASE;
      END;
   END LOOP;

   -- We zetten de locatie bij de melding gelijk aan de locatie van het kenmerk bij betreffende opdracht.
   FOR rec IN locatie
   LOOP
      BEGIN
         v_errorhint :=
               'Locatie melding '
            || rec.mld_melding_key
            || ' wijzigen van  '
            || rec.locatie_melding
            || ' naar '
            || rec.locatie_opdracht;

         CASE
            WHEN rec.loc_opdr_key IS NULL
            THEN
               v_locatie_key := 61; -- Dit is de locatiekey voor Hoofdkantoor. Als de melding niet gekoppeld kan worden aan een bestaande locatie, dan moet deze gekoppeld worden aan locatie Hoofdkantoor.
            ELSE
               v_locatie_key := rec.loc_opdr_key;
         END CASE;

         UPDATE mld_melding
            SET mld_alg_locatie_key = v_locatie_key,
                mld_alg_onroerendgoed_keys = NULL
          WHERE mld_melding_key = rec.mld_melding_key;

         fac.trackaction (
            'MLDUPD',
            rec.mld_melding_key,
            NULL,
            NULL,
               'Locatie: '
            || rec.locatie_melding
            || ' --> '
            || rec.locatie_opdracht);
      END;
   END LOOP;

   -- We zetten de short description vanuit mld_opdr_kenmerk bij de melding in onderwerp/omschrijving (afhankelijk van lengte).
   FOR rec IN descr
   LOOP
      BEGIN
         v_errorhint :=
               'Short description Servicenow bij melding '
            || rec.mld_melding_key
            || ' overnemen ';

         v_lengte := rec.lengte;

         UPDATE mld_melding
            SET mld_melding_onderwerp = SUBSTR (rec.short_description, 1, 80)
          WHERE mld_melding_key = rec.mld_melding_key;

         --Indien short_description te lang voor mld_onderwerp (80), dan ook aanvullen bij omschrijving
         IF v_lengte > 80
         THEN
            UPDATE mld_melding
               SET mld_melding_omschrijving =
                         rec.mld_melding_omschrijving
                      || CHR (10)
                      || 'Short description Servicenow: '
                      || rec.short_description
             WHERE mld_melding_key = rec.mld_melding_key;
         END IF;

         fac.trackaction (
            'MLDUPD',
            rec.mld_melding_key,
            NULL,
            NULL,
            'Onderwerp: (leeg) --> ' || SUBSTR (rec.short_description, 1, 80));
      END;
   END LOOP;
END;
/

----- Rapportage-views -----------------------------------------------------------------------------

CREATE OR REPLACE VIEW hcas_v_rap_qrc_ins_mld
AS
   SELECT i.ins_deel_omschrijving hide_f_sort,
          l.alg_locatie_code || ' ' || l.alg_locatie_omschrijving
             fclt_f_locatie,
          o.alg_gebouw_omschrijving fclt_f_gebouw,
          o.alg_plaatsaanduiding fclt_f_plaats,
          d.ins_discipline_omschrijving fclt_f_discipline,
          g.ins_srtgroep_omschrijving fclt_f_objectgroep,
          s.ins_srtdeel_omschrijving fclt_f_objectsoort,
          i.ins_deel_omschrijving fclt_f_identificatie,
          b.fac_bookmark_naam fclt_f_bookmark,
          i.ins_deel_key,
          s.ins_srtdeel_key,
          i.ins_discipline_key fclt_3d_discipline_key,
          l.alg_locatie_key fclt_3d_locatie_key,
          i.ins_alg_ruimte_type,
          i.ins_alg_ruimte_key,
          b.fac_bookmark_id hide_f_bookmark_id
     FROM ins_deel i,
          ins_v_alg_overzicht o,
          ins_srtdeel s,
          ins_srtgroep g,
          ins_discipline d,
          alg_locatie l,
          fac_bookmark b,
          mld_stdmelding sm,
          mld_stdmelding_srtinst si
    WHERE b.fac_bookmark_path = 'appl/pda/melding.asp'
          AND b.fac_bookmark_query LIKE
                '%stdm_key=' || sm.mld_stdmelding_key || '%'
          AND (b.fac_bookmark_expire IS NULL
               OR b.fac_bookmark_expire > SYSDATE)
          AND ins_deel_verwijder IS NULL
          AND i.ins_deel_module = 'INS'
          AND i.ins_deel_parent_key IS NULL
          AND s.ins_srtdeel_key = i.ins_srtdeel_key
          AND g.ins_srtgroep_key = s.ins_srtgroep_key
          AND d.ins_discipline_key = g.ins_discipline_key
          AND o.alg_onroerendgoed_keys = i.ins_alg_ruimte_key
          AND o.alg_onroerendgoed_type = i.ins_alg_ruimte_type
          AND i.ins_alg_ruimte_type IN ('T', 'R', 'W')
          AND o.alg_locatie_key = i.ins_alg_locatie_key
          AND i.ins_alg_locatie_key = l.alg_locatie_key
          AND sm.mld_stdmelding_key = si.mld_stdmelding_key
          AND si.ins_srtinstallatie_key =
                DECODE (si.ins_srtinstallatie_niveau,
                        'S', i.ins_srtdeel_key,
                        'G', s.ins_srtgroep_key,
                        'D', g.ins_discipline_key);

CREATE OR REPLACE VIEW hcas_v_rap_qrc_ins
AS
   SELECT i.ins_deel_omschrijving hide_f_sort,
          l.alg_locatie_code || ' ' || l.alg_locatie_omschrijving
             fclt_f_locatie,
          o.alg_gebouw_omschrijving fclt_f_gebouw,
          o.alg_plaatsaanduiding fclt_f_plaats,
          d.ins_discipline_omschrijving fclt_f_discipline,
          g.ins_srtgroep_omschrijving fclt_f_objectgroep,
          s.ins_srtdeel_omschrijving fclt_f_objectsoort,
          i.ins_deel_omschrijving fclt_f_identificatie,
          b.fac_bookmark_naam fclt_f_bookmark,
          i.ins_deel_key,
          s.ins_srtdeel_key,
          i.ins_discipline_key fclt_3d_discipline_key,
          l.alg_locatie_key fclt_3d_locatie_key,
          i.ins_alg_ruimte_type,
          i.ins_alg_ruimte_key,
          b.fac_bookmark_id hide_f_bookmark_id
     FROM ins_deel i,
          ins_v_alg_overzicht o,
          ins_srtdeel s,
          ins_srtgroep g,
          ins_discipline d,
          alg_locatie l,
          fac_bookmark b
    WHERE     b.fac_bookmark_path = 'appl/pda/ins_deel.asp'
          AND COALESCE (b.fac_bookmark_expire, SYSDATE + 1) > SYSDATE
          AND ins_deel_verwijder IS NULL
          AND COALESCE (i.ins_deel_vervaldatum, SYSDATE + 1) > SYSDATE
          AND i.ins_deel_module = 'INS'
          AND i.ins_deel_parent_key IS NULL
          AND s.ins_srtdeel_key = i.ins_srtdeel_key
          AND g.ins_srtgroep_key = s.ins_srtgroep_key
          AND d.ins_discipline_key = g.ins_discipline_key
          AND o.alg_onroerendgoed_keys = i.ins_alg_ruimte_key
          AND o.alg_onroerendgoed_type = i.ins_alg_ruimte_type
          AND i.ins_alg_ruimte_type IN ('T', 'R', 'W')
          AND o.alg_locatie_key = i.ins_alg_locatie_key
          AND l.alg_locatie_key = i.ins_alg_locatie_key;

--- HCAS#37147 rapportage met aantallen nog actieve medewerkers per afdeling

CREATE OR REPLACE VIEW HCAS_V_RAP_MDW_AFDELING
(
   AANTAL,
   AFDELING,
   AFDELINGOMSCHRIJVING,
   KOSTENPLAATS
)
AS
     SELECT COUNT (prs_perslid_key),
            a.prs_afdeling_upper,
            PRS_AFDELING_OMSCHRIJVING,
            PRS_KOSTENPLAATS_KEY
       FROM prs_v_aanwezigperslid p, prs_afdeling a
      WHERE P.PRS_AFDELING_KEY(+) = A.PRS_AFDELING_KEY
            AND prs_afdeling_verwijder IS NULL
   GROUP BY a.prs_afdeling_upper,
            PRS_AFDELING_OMSCHRIJVING,
            PRS_KOSTENPLAATS_KEY;


CREATE OR REPLACE PROCEDURE hcas_export_kpi (p_applname   IN VARCHAR2,
                                             p_applrun    IN VARCHAR2,
                                             p_filedir    IN VARCHAR2,
                                             p_filename   IN VARCHAR2)
AS
   v_aanduiding            VARCHAR2 (200);
   v_errorhint             VARCHAR2 (1000);
   v_errormsg              VARCHAR2 (1000);
   oracle_err_num          NUMBER;
   oracle_err_mes          VARCHAR2 (200);
   v_count                 NUMBER;

   --- variabelen die gebruikt worden in bepalen functie herstel
   v_uitvoertijd_fh_uren mld_stdmelding.mld_stdmelding_t_uitvoertijd%TYPE
         := MLD_T_UITVOERTIJD (NULL, NULL);       -- constructor initialisatie
   v_uitvoertijd_fh_dagen mld_stdmelding.mld_stdmelding_t_uitvoertijd%TYPE
         := MLD_T_UITVOERTIJD (NULL, NULL);
   v_uitvoertijd_rep_uren mld_stdmelding.mld_stdmelding_t_uitvoertijd%TYPE
         := MLD_T_UITVOERTIJD (NULL, NULL);
   v_uitvoertijd_rep_dagen mld_stdmelding.mld_stdmelding_t_uitvoertijd%TYPE
         := MLD_T_UITVOERTIJD (NULL, NULL);
   v_urenperdag            NUMBER (10, 3);
   v_eerstedag             NUMBER (10, 3);
   v_laatstedag            NUMBER (10, 3);
   v_heledagen             NUMBER (10);
   v_vrijedagen            NUMBER;
   v_begindatum            DATE;    -- = datum_uitgifte (is datum / tijd veld)
   v_functiehersteldatum   DATE; -- = datum functieherstel (is datum/ tijd veld)
   v_einddatum             DATE;   -- = datum reparatie (is datum / tijd veld)
   v_pBeginWerkUur         NUMBER (10, 3); -- = tijd waarop klok tikt, dus service window (let op notatie in kenmerk: half 8 is 7,5 en niet 7:30!!!)
   v_pEindWerkUur          NUMBER (10, 3); --- = tijd wanneer klok stopt, dus service window
   v_pmode                 NUMBER (10);                    -- = staat in tabel
   v_uitvoertijdtype       VARCHAR2 (50);                    --- uren en dagen


   -- alle opdrachtgegevens die nog niet in cust tabel zitten
   -- want die moeten dan nog toegevoegd worden
   CURSOR KPI
   IS
      SELECT b.prs_bedrijf_key,
             b.prs_bedrijf_naam,
             uk1_van.prs_kenmerklink_waarde AS uk1_van,
             uk1_tot.prs_kenmerklink_waarde AS uk1_tot,
             uk2_van.prs_kenmerklink_waarde AS uk2_van,
             uk2_tot.prs_kenmerklink_waarde AS uk2_tot,
             DECODE (onderhoud_obj.urgentieklasse,
                     'Klasse 2', 1,
                     'Klasse 1', 0) ---- conform FCLT standaard: 1 is alleen werdagen, 0 is alle dagen
                pMode,
             DECODE (onderhoud_obj.urgentieklasse,
                     'Klasse 2', uk2_van.prs_kenmerklink_waarde,
                     'Klasse 1', uk1_van.prs_kenmerklink_waarde)
                GELDEND_FH_VAN,
             DECODE (onderhoud_obj.urgentieklasse,
                     'Klasse 2', uk2_tot.prs_kenmerklink_waarde,
                     'Klasse 1', uk1_tot.prs_kenmerklink_waarde)
                GELDEND_FH_TOT,
             onderhoud_obj.ins_deel_omschrijving,
             opdracht.ins_deel_key,
             onderhoud_obj.conditieklasse,
             onderhoud_obj.urgentieklasse,
             onderhoud_obj.FH_tijd AS max_fh_tijd, --- de maximale functiehersteltijd wordt uit een eigen tabel urgentie klasse gehaald, dit is de tijd in uren
             DECODE (onderhoud_obj.urgentieklasse, -----de maximale tijd voor reparatie is bepaald op 5 dagen voor objecten van klasse 2 en 3 dagen voor klasse 1
                     'Klasse 2', 5,
                     'Klasse 1', 3)
                max_rep_tijd,
             opdracht.mld_melding_key,
             opdracht.mld_opdr_key,
             opdracht.mld_typeopdr_key,
             opdracht.mld_statusopdr_key,
             opdracht.mld_statusopdr_omschrijving,
             opdracht.datum_uitgifte,
             opdracht.functieherstel,
             opdracht.datum_functieherstel,
             opdracht.gerepareerd,
             opdracht.datum_reparatie,
             opdracht.herhaalstoring
        FROM prs_bedrijf b,
             (SELECT *
                FROM prs_kenmerklink
               WHERE prs_kenmerk_key = 1140) uk1_van,
             (SELECT *
                FROM prs_kenmerklink
               WHERE prs_kenmerk_key = 1143) uk1_tot,
             (SELECT *
                FROM prs_kenmerklink
               WHERE prs_kenmerk_key = 1141) uk2_van,
             (SELECT *
                FROM prs_kenmerklink
               WHERE prs_kenmerk_key = 1144) uk2_tot,
             (SELECT o.ins_deel_key,
                     o.ins_deel_omschrijving,
                     fac.safe_to_number (
                        onderhoudsleverancier.ins_kenmerkdeel_waarde)
                        AS prs_bedrijf_key,
                     conditieklasse.ins_kenmerkdeel_waarde AS conditieklasse,
                     urgentieklasse.fac_usrdata_omschr AS urgentieklasse,
                     urgentieklasse.fac_usrdata_prijs AS fh_tijd
                FROM ins_deel o,
                     (SELECT kd.*
                        FROM ins_kenmerkdeel kd, ins_kenmerk km
                       WHERE kd.ins_kenmerk_key = km.ins_kenmerk_key
                             AND km.ins_srtkenmerk_key = 62)
                     onderhoudsleverancier,
                     (SELECT kd.*, ud.fac_usrdata_omschr, fac_usrdata_prijs
                        FROM ins_kenmerkdeel kd,
                             ins_kenmerk km,
                             fac_usrdata ud
                       WHERE kd.ins_kenmerk_key = km.ins_kenmerk_key
                             AND kd.ins_kenmerkdeel_waarde =
                                   ud.fac_usrdata_key
                             AND km.ins_srtkenmerk_key = 301) urgentieklasse,
                     (SELECT kd.*
                        FROM ins_kenmerkdeel kd, ins_kenmerk km
                       WHERE kd.ins_kenmerk_key = km.ins_kenmerk_key
                             AND km.ins_srtkenmerk_key = 321) conditieklasse
               WHERE     o.ins_deel_verwijder IS NULL
                     AND onderhoudsleverancier.ins_deel_key = o.ins_deel_key
                     AND conditieklasse.ins_deel_key(+) = o.ins_deel_key
                     AND urgentieklasse.ins_deel_key = o.ins_deel_key)
             onderhoud_obj,
             (SELECT mo.ins_deel_key,
                     m.mld_melding_key,
                     o.mld_opdr_key,
                     o.mld_typeopdr_key,
                     o.mld_statusopdr_key,
                     so.mld_statusopdr_omschrijving,
                     fac.safe_to_number (o.mld_uitvoerende_keys)
                        AS uitv_bedrijf,
                     fac.safe_to_date (
                           datum_uitg.mld_kenmerkopdr_waarde
                        || ' '
                        || tijd_uitg.mld_kenmerkopdr_waarde,
                        'dd-mm-yyyy hh24:mi')
                        AS datum_uitgifte,
                     functieherstel.fac_usrdata_omschr AS functieherstel,
                     fac.safe_to_date (
                           datum_functieherstel.mld_kenmerkopdr_waarde
                        || ' '
                        || tijd_functieherstel.mld_kenmerkopdr_waarde,
                        'dd-mm-yyyy hh24:mi')
                        AS datum_functieherstel,
                     reparatie.fac_usrdata_omschr AS gerepareerd,
                     fac.safe_to_date (
                           datum_reparatie.mld_kenmerkopdr_waarde
                        || ' '
                        || tijd_reparatie.mld_kenmerkopdr_waarde,
                        'dd-mm-yyyy hh24:mi')
                        AS datum_reparatie,
                     herhaalstoring.fac_usrdata_omschr AS herhaalstoring
                FROM mld_melding_object mo,
                     mld_melding m,
                     mld_opdr o,
                     mld_statusopdr so,
                     (SELECT *
                        FROM mld_kenmerkopdr ko
                       WHERE mld_kenmerk_key = 402) datum_uitg,
                     (SELECT *
                        FROM mld_kenmerkopdr ko
                       WHERE mld_kenmerk_key = 403) tijd_uitg,
                     (SELECT *
                        FROM mld_kenmerkopdr ko, fac_usrdata ud
                       WHERE ko.mld_kenmerkopdr_waarde = ud.fac_usrdata_key
                             AND ud.fac_usrtab_key = 241
                             AND mld_kenmerk_key = 423) functieherstel,
                     (SELECT *
                        FROM mld_kenmerkopdr ko
                       WHERE mld_kenmerk_key = 422) datum_functieherstel,
                     (SELECT *
                        FROM mld_kenmerkopdr ko
                       WHERE mld_kenmerk_key = 425) tijd_functieherstel,
                     (SELECT *
                        FROM mld_kenmerkopdr ko, fac_usrdata ud
                       WHERE ko.mld_kenmerkopdr_waarde = ud.fac_usrdata_key
                             AND ud.fac_usrtab_key = 241
                             AND mld_kenmerk_key = 441) reparatie,
                     (SELECT *
                        FROM mld_kenmerkopdr ko
                       WHERE mld_kenmerk_key = 427) datum_reparatie,
                     (SELECT *
                        FROM mld_kenmerkopdr ko
                       WHERE mld_kenmerk_key = 428) tijd_reparatie,
                     (SELECT *
                        FROM mld_kenmerkopdr ko, fac_usrdata ud
                       WHERE ko.mld_kenmerkopdr_waarde = ud.fac_usrdata_key
                             AND ud.fac_usrtab_key = 261
                             AND mld_kenmerk_key = 461) herhaalstoring
               WHERE     mo.mld_melding_key = m.mld_melding_key
                     AND o.mld_melding_key = m.mld_melding_key
                     AND o.mld_statusopdr_key = so.mld_statusopdr_key
                     AND datum_uitg.mld_opdr_key = o.mld_opdr_key
                     AND tijd_uitg.mld_opdr_key = o.mld_opdr_key
                     AND functieherstel.mld_opdr_key(+) = o.mld_opdr_key
                     AND datum_functieherstel.mld_opdr_key(+) =
                           o.mld_opdr_key
                     AND tijd_functieherstel.mld_opdr_key(+) = o.mld_opdr_key
                     AND reparatie.mld_opdr_key(+) = o.mld_opdr_key
                     AND datum_reparatie.mld_opdr_key(+) = o.mld_opdr_key
                     AND herhaalstoring.mld_opdr_key(+) = o.mld_opdr_key
                     AND tijd_reparatie.mld_opdr_key(+) = o.mld_opdr_key)
             opdracht
       WHERE     prs_bedrijf_verwijder IS NULL
             AND prs_bedrijf_leverancier = 1
             AND uk1_van.prs_link_key = b.prs_bedrijf_key
             AND uk1_tot.prs_link_key = b.prs_bedrijf_key
             AND uk2_van.prs_link_key = b.prs_bedrijf_key
             AND uk2_tot.prs_link_key = b.prs_bedrijf_key
             AND onderhoud_obj.prs_bedrijf_key = b.prs_bedrijf_key
             AND opdracht.uitv_bedrijf = b.prs_bedrijf_key
             AND opdracht.ins_deel_key = onderhoud_obj.ins_deel_key
             AND opdracht.mld_statusopdr_key = 6 ---    status van de opdracht is afgemeld
             AND opdracht.mld_opdr_key NOT IN --- opdracht is nog niet geëxporteerd
                      (SELECT mld_opdr_key FROM hcas_kpi_leveranciers);
BEGIN
   FOR rec IN KPI
   LOOP
      INSERT INTO hcas_kpi_leveranciers (uitv_bedrijf,
                                         prs_bedrijf_naam,
                                         UK1_van,
                                         UK1_tot,
                                         UK2_van,
                                         UK2_tot,
                                         pmode,
                                         geldend_FH_van,
                                         geldend_FH_tot,
                                         ins_deel_omschrijving,
                                         ins_deel_key,
                                         conditieklasse,
                                         urgentieklasse,
                                         max_fh_tijd,
                                         max_rep_tijd,
                                         mld_melding_key,
                                         mld_opdr_key,
                                         mld_typeopdr_key,
                                         mld_statusopdr_key,
                                         mld_statusopdr_omschrijving,
                                         datum_uitgifte,
                                         functieherstel,
                                         datum_functieherstel,
                                         gerepareerd,
                                         datum_reparatie,
                                         herhaalstoring)
          VALUES (rec.prs_bedrijf_key,
                  rec.prs_bedrijf_naam,
                  rec.uk1_van,
                  rec.uk1_tot,
                  rec.uk2_van,
                  rec.uk2_tot,
                  rec.pmode,
                  rec.geldend_fh_van,
                  rec.geldend_fh_tot,
                  rec.ins_deel_omschrijving,
                  rec.ins_deel_key,
                  rec.conditieklasse,
                  rec.urgentieklasse,
                  rec.max_fh_tijd,
                  rec.max_rep_tijd,
                  rec.mld_melding_key,
                  rec.mld_opdr_key,
                  rec.mld_typeopdr_key,
                  rec.mld_statusopdr_key,
                  rec.mld_statusopdr_omschrijving,
                  rec.datum_uitgifte,
                  rec.functieherstel,
                  rec.datum_functieherstel,
                  rec.gerepareerd,
                  rec.datum_reparatie,
                  rec.herhaalstoring);

      COMMIT;

      --- tabel is nu bijgewerkt, nu de hersteltijd berekenen
      --- variabelen die gebruikt worden in bepalen functie herstel
      v_begindatum := rec.datum_uitgifte;
      v_functiehersteldatum := rec.datum_functieherstel;
      v_einddatum := rec.datum_reparatie;
      v_pBeginWerkUur := rec.geldend_fh_van;
      v_pEindWerkUur := rec.geldend_fh_tot;
      v_pmode := rec.pmode;
      v_uitvoertijdtype := 'UREN';

      --- eerst FH hersteltijd berekenen in uren, later FH tijd in dagen
      IF     v_begindatum IS NOT NULL
         AND v_functiehersteldatum IS NOT NULL
         AND v_pMode BETWEEN 0 AND 2
      THEN
         IF v_begindatum > v_functiehersteldatum
         THEN
            v_uitvoertijd_fh_uren :=
               fac.datumtijdnaaruitvoertijd (v_begindatum,
                                             v_functiehersteldatum,
                                             v_uitvoertijdtype,
                                             v_pBeginWerkUur,
                                             v_pEindWerkUur,
                                             v_pMode);

            v_uitvoertijd_fh_uren.tijdsduur :=
               -v_uitvoertijd_fh_uren.tijdsduur;
         ELSIF v_pMode = 2
         THEN
            --uitvoertijd := (v_functiehersteldatum - v_begindatum) * 24;
            -- Zo simpel kan het zijn igv. 24/7!
            -- default/uitvoertijdtype IN ('U', 'UREN')
            v_uitvoertijd_fh_uren.tijdsduur :=
               (v_functiehersteldatum - v_begindatum) * 24;
         --v_uitvoertijd_fh.eenheid := 'U';
         ELSIF     v_pBeginWerkUur BETWEEN 0 AND 24
               AND v_pEindWerkUur BETWEEN 0 AND 24
               AND v_pEindWerkUur > v_pBeginWerkUur
         THEN
            v_urenperdag := v_pEindWerkUur - v_pBeginWerkUur;
            v_eerstedag :=
               v_pEindWerkUur
               - (TRUNC (v_begindatum, 'MI') - TRUNC (v_begindatum)) * 24;
            v_eerstedag := LEAST (GREATEST (0, v_eerstedag), v_urenperdag);
            v_laatstedag :=
               (TRUNC (v_functiehersteldatum, 'MI')
                - TRUNC (v_functiehersteldatum))
               * 24
               - v_pBeginWerkUur;
            v_laatstedag := LEAST (GREATEST (0, v_laatstedag), v_urenperdag);

            IF v_pMode = 0
            THEN
               -- Oppassen als begin/eind op een vrije dag valt,
               -- dan moeten eerste/laatste dag gewoon 0 uur zijn.
               SELECT COUNT ( * )
                 INTO v_vrijedagen
                 FROM mld_vrije_dagen
                WHERE mld_vrije_dagen_datum = TRUNC (v_begindatum);

               IF v_vrijedagen = 1
               THEN
                  v_eerstedag := 0;
               END IF;

               SELECT COUNT ( * )
                 INTO v_vrijedagen
                 FROM mld_vrije_dagen
                WHERE mld_vrije_dagen_datum = TRUNC (v_functiehersteldatum);

               IF v_vrijedagen = 1
               THEN
                  v_laatstedag := 0;
               END IF;

               IF TRUNC (v_begindatum) = TRUNC (v_functiehersteldatum)
               THEN
                  IF v_eerstedag + v_laatstedag > 0         -- geen vrije dag!
                  THEN
                     -- Als begindatum=einddatum én werkdag, dan 1 dag corrigeren!
                     v_heledagen := -1;
                  ELSE
                     -- Als begindatum=einddatum én vrije dag, dan geen correctie!
                     v_heledagen := 0;
                  END IF;
               ELSE
                  -- Als begindatum<>einddatum, dan alleen nog vrije dagen tussen
                  -- begin+1 en eind-1 corrigeren (en altijd 0 als begin+1=eind)!
                  SELECT COUNT ( * )
                    INTO v_vrijedagen
                    FROM mld_vrije_dagen
                   WHERE mld_vrije_dagen_datum BETWEEN TRUNC (
                                                          v_begindatum + 1)
                                                   AND  v_functiehersteldatum
                                                        - 1;

                  IF TRUNC (v_begindatum + 1) = TRUNC (v_functiehersteldatum)
                  THEN
                     v_heledagen := 0;
                  ELSE
                     v_heledagen :=
                          TRUNC (v_functiehersteldatum)
                        - TRUNC (v_begindatum + 1)
                        - v_vrijedagen;
                  END IF;
               END IF;
            ELSE                                                  -- pMode = 1
               -- Oppassen als begin/eind in het weekend of zo valt,
               -- dan moeten eerste/laatste dag gewoon 0 uur zijn.
               IF fac.iswerkdag (v_begindatum) = 0
               THEN
                  v_eerstedag := 0;
               END IF;

               IF fac.iswerkdag (v_functiehersteldatum) = 0
               THEN
                  v_laatstedag := 0;
                  v_heledagen :=
                     fac.count_Work_Days (TRUNC (v_begindatum),
                                          TRUNC (v_functiehersteldatum));
               ELSE
                  v_heledagen :=
                     fac.count_Work_Days (TRUNC (v_begindatum),
                                          TRUNC (v_functiehersteldatum))
                     - 1;
               END IF;
            END IF;

            -- v_uitvoertijd_fh_uren :=  v_eerstedag + v_laatstedag + v_heledagen * v_urenperdag;
            -- default/uitvoertijdtype IN ('U', 'UREN')
            v_uitvoertijd_fh_uren.tijdsduur :=
               v_eerstedag + v_laatstedag + v_heledagen * v_urenperdag;
         --v_uitvoertijd_fh.eenheid := 'U';
         END IF;

         UPDATE HCAS_KPI_LEVERANCIERS K
            SET k.functiehersteltijd_uren = v_uitvoertijd_fh_uren.tijdsduur
          WHERE k.mld_opdr_key = rec.mld_opdr_key;
      END IF;

      COMMIT;

      --- FH tijd is nu bekend in uren, vervolgens in dagen berekenen
      --- variabelen die gebruikt worden in bepalen functie herstel
      v_begindatum := rec.datum_uitgifte;
      v_functiehersteldatum := rec.datum_functieherstel;
      v_einddatum := rec.datum_reparatie;
      v_pBeginWerkUur := rec.geldend_fh_van;
      v_pEindWerkUur := rec.geldend_fh_tot;
      v_pmode := rec.pmode;
      v_uitvoertijdtype := 'DAGEN';

      --- eerst FH hersteltijd berekenen in uren, later reparatie
      IF     v_begindatum IS NOT NULL
         AND v_functiehersteldatum IS NOT NULL
         AND v_pMode BETWEEN 0 AND 2
      THEN
         IF v_begindatum > v_functiehersteldatum
         THEN
            v_uitvoertijd_fh_dagen :=
               fac.datumtijdnaaruitvoertijd (v_begindatum,
                                             v_functiehersteldatum,
                                             v_uitvoertijdtype,
                                             v_pBeginWerkUur,
                                             v_pEindWerkUur,
                                             v_pMode);

            v_uitvoertijd_fh_dagen.tijdsduur :=
               -v_uitvoertijd_fh_dagen.tijdsduur;
         ELSIF v_pMode = 2
         THEN
            --uitvoertijd := (v_functiehersteldatum - v_begindatum) * 24;
            -- Zo simpel kan het zijn igv. 24/7!
            -- default/uitvoertijdtype IN ('U', 'UREN')
            v_uitvoertijd_fh_dagen.tijdsduur :=
               v_functiehersteldatum - v_begindatum;
         --   v_uitvoertijd_fh.eenheid := 'D';

         ELSIF     v_pBeginWerkUur BETWEEN 0 AND 24
               AND v_pEindWerkUur BETWEEN 0 AND 24
               AND v_pEindWerkUur > v_pBeginWerkUur
         THEN
            v_urenperdag := v_pEindWerkUur - v_pBeginWerkUur;
            v_eerstedag :=
               v_pEindWerkUur
               - (TRUNC (v_begindatum, 'MI') - TRUNC (v_begindatum)) * 24;
            v_eerstedag := LEAST (GREATEST (0, v_eerstedag), v_urenperdag);
            v_laatstedag :=
               (TRUNC (v_functiehersteldatum, 'MI')
                - TRUNC (v_functiehersteldatum))
               * 24
               - v_pBeginWerkUur;
            v_laatstedag := LEAST (GREATEST (0, v_laatstedag), v_urenperdag);

            IF v_pMode = 0
            THEN
               -- Oppassen als begin/eind op een vrije dag valt,
               -- dan moeten eerste/laatste dag gewoon 0 uur zijn.
               SELECT COUNT ( * )
                 INTO v_vrijedagen
                 FROM mld_vrije_dagen
                WHERE mld_vrije_dagen_datum = TRUNC (v_begindatum);

               IF v_vrijedagen = 1
               THEN
                  v_eerstedag := 0;
               END IF;

               SELECT COUNT ( * )
                 INTO v_vrijedagen
                 FROM mld_vrije_dagen
                WHERE mld_vrije_dagen_datum = TRUNC (v_functiehersteldatum);

               IF v_vrijedagen = 1
               THEN
                  v_laatstedag := 0;
               END IF;

               IF TRUNC (v_begindatum) = TRUNC (v_functiehersteldatum)
               THEN
                  IF v_eerstedag + v_laatstedag > 0         -- geen vrije dag!
                  THEN
                     -- Als begindatum=einddatum én werkdag, dan 1 dag corrigeren!
                     v_heledagen := -1;
                  ELSE
                     -- Als begindatum=einddatum én vrije dag, dan geen correctie!
                     v_heledagen := 0;
                  END IF;
               ELSE
                  -- Als begindatum<>einddatum, dan alleen nog vrije dagen tussen
                  -- begin+1 en eind-1 corrigeren (en altijd 0 als begin+1=eind)!
                  SELECT COUNT ( * )
                    INTO v_vrijedagen
                    FROM mld_vrije_dagen
                   WHERE mld_vrije_dagen_datum BETWEEN TRUNC (
                                                          v_begindatum + 1)
                                                   AND  v_functiehersteldatum
                                                        - 1;

                  IF TRUNC (v_begindatum + 1) = TRUNC (v_functiehersteldatum)
                  THEN
                     v_heledagen := 0;
                  ELSE
                     v_heledagen :=
                          TRUNC (v_functiehersteldatum)
                        - TRUNC (v_begindatum + 1)
                        - v_vrijedagen;
                  END IF;
               END IF;
            ELSE                                                  -- pMode = 1
               -- Oppassen als begin/eind in het weekend of zo valt,
               -- dan moeten eerste/laatste dag gewoon 0 uur zijn.
               IF fac.iswerkdag (v_begindatum) = 0
               THEN
                  v_eerstedag := 0;
               END IF;

               IF fac.iswerkdag (v_functiehersteldatum) = 0
               THEN
                  v_laatstedag := 0;
                  v_heledagen :=
                     fac.count_Work_Days (TRUNC (v_begindatum),
                                          TRUNC (v_functiehersteldatum));
               ELSE
                  v_heledagen :=
                     fac.count_Work_Days (TRUNC (v_begindatum),
                                          TRUNC (v_functiehersteldatum))
                     - 1;
               END IF;
            END IF;

            -- v_uitvoertijd_fh_uren :=  v_eerstedag + v_laatstedag + v_heledagen * v_urenperdag;
            -- default/uitvoertijdtype IN ('D', 'DAGEN')
            v_uitvoertijd_fh_dagen.tijdsduur :=
               (v_eerstedag + v_laatstedag + v_heledagen * v_urenperdag)
               / v_urenperdag;
         -- v_uitvoertijd_fh.eenheid := 'D';
         END IF;

         UPDATE HCAS_KPI_LEVERANCIERS K
            SET k.functiehersteltijd_dagen = v_uitvoertijd_fh_dagen.tijdsduur
          WHERE k.mld_opdr_key = rec.mld_opdr_key;
      END IF;

      COMMIT;

      -- variabelen die gebruikt worden in bepalen reparatie, eerst in dagen
      -- bij een reparatie tellen nooit weekenden en feestdagen mee
      -- pmode is daarom conform FCLT standaard: 1 is alleen werkdagen
      v_begindatum := rec.datum_uitgifte;
      v_einddatum := rec.datum_reparatie;
      v_pBeginWerkUur := rec.geldend_fh_van;
      v_pEindWerkUur := rec.geldend_fh_tot;
      v_pmode := 1;
      v_uitvoertijdtype := 'DAGEN';

      IF     v_begindatum IS NOT NULL
         AND v_einddatum IS NOT NULL
         AND v_pMode BETWEEN 0 AND 2
      THEN
         IF v_begindatum > v_einddatum
         THEN
            v_uitvoertijd_rep_dagen :=
               fac.datumtijdnaaruitvoertijd (v_begindatum,
                                             v_einddatum,
                                             v_uitvoertijdtype,
                                             v_pBeginWerkUur,
                                             v_pEindWerkUur,
                                             v_pMode);

            v_uitvoertijd_rep_dagen.tijdsduur :=
               -v_uitvoertijd_rep_dagen.tijdsduur;
         ELSIF v_pMode = 2
         THEN
            --uitvoertijd := (v_functiehersteldatum - v_begindatum) * 24;
            -- Zo simpel kan het zijn igv. 24/7!
            -- Per 5.4.3 kunnen hier gebroken dagen worden teruggegeven!
            v_uitvoertijd_rep_dagen.tijdsduur := v_einddatum - v_begindatum;
            v_uitvoertijd_rep_dagen.eenheid := 'D';
         ELSIF     v_pBeginWerkUur BETWEEN 0 AND 24
               AND v_pEindWerkUur BETWEEN 0 AND 24
               AND v_pEindWerkUur > v_pBeginWerkUur
         THEN
            v_urenperdag := v_pEindWerkUur - v_pBeginWerkUur;
            v_eerstedag :=
               v_pEindWerkUur
               - (TRUNC (v_begindatum, 'MI') - TRUNC (v_begindatum)) * 24;
            v_eerstedag := LEAST (GREATEST (0, v_eerstedag), v_urenperdag);
            v_laatstedag :=
               (TRUNC (v_einddatum, 'MI') - TRUNC (v_einddatum)) * 24
               - v_pBeginWerkUur;
            v_laatstedag := LEAST (GREATEST (0, v_laatstedag), v_urenperdag);

            IF v_pMode = 0
            THEN
               -- Oppassen als begin/eind op een vrije dag valt,
               -- dan moeten eerste/laatste dag gewoon 0 uur zijn.
               SELECT COUNT ( * )
                 INTO v_vrijedagen
                 FROM mld_vrije_dagen
                WHERE mld_vrije_dagen_datum = TRUNC (v_begindatum);

               IF v_vrijedagen = 1
               THEN
                  v_eerstedag := 0;
               END IF;

               SELECT COUNT ( * )
                 INTO v_vrijedagen
                 FROM mld_vrije_dagen
                WHERE mld_vrije_dagen_datum = TRUNC (v_einddatum);

               IF v_vrijedagen = 1
               THEN
                  v_laatstedag := 0;
               END IF;

               IF TRUNC (v_begindatum) = TRUNC (v_einddatum)
               THEN
                  IF v_eerstedag + v_laatstedag > 0         -- geen vrije dag!
                  THEN
                     -- Als begindatum=einddatum én werkdag, dan 1 dag corrigeren!
                     v_heledagen := -1;
                  ELSE
                     -- Als begindatum=einddatum én vrije dag, dan geen correctie!
                     v_heledagen := 0;
                  END IF;
               ELSE
                  -- Als begindatum<>einddatum, dan alleen nog vrije dagen tussen
                  -- begin+1 en eind-1 corrigeren (en altijd 0 als begin+1=eind)!
                  SELECT COUNT ( * )
                    INTO v_vrijedagen
                    FROM mld_vrije_dagen
                   WHERE mld_vrije_dagen_datum BETWEEN TRUNC (
                                                          v_begindatum + 1)
                                                   AND  v_einddatum - 1;

                  IF TRUNC (v_begindatum + 1) = TRUNC (v_einddatum)
                  THEN
                     v_heledagen := 0;
                  ELSE
                     v_heledagen :=
                          TRUNC (v_einddatum)
                        - TRUNC (v_begindatum + 1)
                        - v_vrijedagen;
                  END IF;
               END IF;
            ELSE                                                  -- pMode = 1
               -- Oppassen als begin/eind in het weekend of zo valt,
               -- dan moeten eerste/laatste dag gewoon 0 uur zijn.
               IF fac.iswerkdag (v_begindatum) = 0
               THEN
                  v_eerstedag := 0;
               END IF;

               IF fac.iswerkdag (v_einddatum) = 0
               THEN
                  v_laatstedag := 0;
                  v_heledagen :=
                     fac.count_Work_Days (TRUNC (v_begindatum),
                                          TRUNC (v_einddatum));
               ELSE
                  v_heledagen :=
                     fac.count_Work_Days (TRUNC (v_begindatum),
                                          TRUNC (v_einddatum))
                     - 1;
               END IF;
            END IF;

            -- v_uitvoertijd_rep_dagen :=  v_eerstedag + v_laatstedag + v_heledagen * v_urenperdag;
            -- Per 5.4.3 kunnen hier gebroken dagen worden teruggegeven!
            v_uitvoertijd_rep_dagen.tijdsduur :=
               (v_eerstedag + v_laatstedag + v_heledagen * v_urenperdag)
               / v_urenperdag;
            v_uitvoertijd_rep_dagen.eenheid := 'D';
         END IF;

         UPDATE HCAS_KPI_LEVERANCIERS K
            SET k.reparatietijd_dagen = v_uitvoertijd_rep_dagen.tijdsduur
          WHERE k.mld_opdr_key = rec.mld_opdr_key;
      END IF;

      COMMIT;

      -- variabelen die gebruikt worden in bepalen reparatie, nu in uren
      -- bij een reparatie tellen nooit weekenden en feestdagen mee
      -- pmode is daarom conform FCLT standaard: 1 is alleen werkdagen
      v_begindatum := rec.datum_uitgifte;
      v_einddatum := rec.datum_reparatie;
      v_pBeginWerkUur := rec.geldend_fh_van;
      v_pEindWerkUur := rec.geldend_fh_tot;
      v_pmode := 1;
      v_uitvoertijdtype := 'UREN';

      IF     v_begindatum IS NOT NULL
         AND v_einddatum IS NOT NULL
         AND v_pMode BETWEEN 0 AND 2
      THEN
         IF v_begindatum > v_einddatum
         THEN
            v_uitvoertijd_rep_uren :=
               fac.datumtijdnaaruitvoertijd (v_begindatum,
                                             v_einddatum,
                                             v_uitvoertijdtype,
                                             v_pBeginWerkUur,
                                             v_pEindWerkUur,
                                             v_pMode);

            v_uitvoertijd_rep_uren.tijdsduur :=
               -v_uitvoertijd_rep_uren.tijdsduur;
         ELSIF v_pMode = 2
         THEN
            v_uitvoertijd_rep_uren.tijdsduur := (v_einddatum - v_begindatum) * 24;
         --   v_uitvoertijd.eenheid := 'U';
         ELSIF     v_pBeginWerkUur BETWEEN 0 AND 24
               AND v_pEindWerkUur BETWEEN 0 AND 24
               AND v_pEindWerkUur > v_pBeginWerkUur
         THEN
            v_urenperdag := v_pEindWerkUur - v_pBeginWerkUur;
            v_eerstedag :=
               v_pEindWerkUur
               - (TRUNC (v_begindatum, 'MI') - TRUNC (v_begindatum)) * 24;
            v_eerstedag := LEAST (GREATEST (0, v_eerstedag), v_urenperdag);
            v_laatstedag :=
               (TRUNC (v_einddatum, 'MI') - TRUNC (v_einddatum)) * 24
               - v_pBeginWerkUur;
            v_laatstedag := LEAST (GREATEST (0, v_laatstedag), v_urenperdag);

            IF v_pMode = 0
            THEN
               -- Oppassen als begin/eind op een vrije dag valt,
               -- dan moeten eerste/laatste dag gewoon 0 uur zijn.
               SELECT COUNT ( * )
                 INTO v_vrijedagen
                 FROM mld_vrije_dagen
                WHERE mld_vrije_dagen_datum = TRUNC (v_begindatum);

               IF v_vrijedagen = 1
               THEN
                  v_eerstedag := 0;
               END IF;

               SELECT COUNT ( * )
                 INTO v_vrijedagen
                 FROM mld_vrije_dagen
                WHERE mld_vrije_dagen_datum = TRUNC (v_einddatum);

               IF v_vrijedagen = 1
               THEN
                  v_laatstedag := 0;
               END IF;

               IF TRUNC (v_begindatum) = TRUNC (v_einddatum)
               THEN
                  IF v_eerstedag + v_laatstedag > 0         -- geen vrije dag!
                  THEN
                     -- Als begindatum=einddatum én werkdag, dan 1 dag corrigeren!
                     v_heledagen := -1;
                  ELSE
                     -- Als begindatum=einddatum én vrije dag, dan geen correctie!
                     v_heledagen := 0;
                  END IF;
               ELSE
                  -- Als begindatum<>einddatum, dan alleen nog vrije dagen tussen
                  -- begin+1 en eind-1 corrigeren (en altijd 0 als begin+1=eind)!
                  SELECT COUNT ( * )
                    INTO v_vrijedagen
                    FROM mld_vrije_dagen
                   WHERE mld_vrije_dagen_datum BETWEEN TRUNC (
                                                          v_begindatum + 1)
                                                   AND  v_einddatum - 1;

                  IF TRUNC (v_begindatum + 1) = TRUNC (v_einddatum)
                  THEN
                     v_heledagen := 0;
                  ELSE
                     v_heledagen :=
                          TRUNC (v_einddatum)
                        - TRUNC (v_begindatum + 1)
                        - v_vrijedagen;
                  END IF;
               END IF;
            ELSE                                                  -- pMode = 1
               -- Oppassen als begin/eind in het weekend of zo valt,
               -- dan moeten eerste/laatste dag gewoon 0 uur zijn.
               IF fac.iswerkdag (v_begindatum) = 0
               THEN
                  v_eerstedag := 0;
               END IF;

               IF fac.iswerkdag (v_einddatum) = 0
               THEN
                  v_laatstedag := 0;
                  v_heledagen :=
                     fac.count_Work_Days (TRUNC (v_begindatum),
                                          TRUNC (v_einddatum));
               ELSE
                  v_heledagen :=
                     fac.count_Work_Days (TRUNC (v_begindatum),
                                          TRUNC (v_einddatum))
                     - 1;
               END IF;
            END IF;

            v_uitvoertijd_rep_uren.tijdsduur :=
               v_eerstedag + v_laatstedag + v_heledagen * v_urenperdag;
         -- v_uitvoertijd.eenheid := 'U';
         END IF;

         UPDATE HCAS_KPI_LEVERANCIERS K
            SET k.reparatietijd_uren = v_uitvoertijd_rep_uren.tijdsduur
          WHERE k.mld_opdr_key = rec.mld_opdr_key;
      END IF;

      COMMIT;
      
      --- Dan moet de status van de opdracht bijgewerkt worden, zodat de opdrachten niet meer gemuteerd kunnen worden
      UPDATE MLD_OPDR o
         SET o.mld_statusopdr_key = 7
       WHERE rec.mld_opdr_key = o.mld_opdr_key;

      COMMIT;
      
   END LOOP;
END;
/



CREATE OR REPLACE VIEW HCAS_V_RAP_FH_REPARATIE
AS
   SELECT mo.ins_deel_key,
          m.mld_melding_key,
          o.mld_opdr_key,
          fac.safe_to_number (o.mld_uitvoerende_keys) AS uitv_bedrijf,
          fac.safe_to_date (
                datum_uitg.mld_kenmerkopdr_waarde
             || ' '
             || tijd_uitg.mld_kenmerkopdr_waarde,
             'dd-mm-yyyy hh24:mi')
             AS datum_uitgifte,
          functieherstel.fac_usrdata_omschr AS functieherstel,
          fac.safe_to_date (
                datum_functieherstel.mld_kenmerkopdr_waarde
             || ' '
             || tijd_functieherstel.mld_kenmerkopdr_waarde,
             'dd-mm-yyyy hh24:mi')
             AS datum_functieherstel,
          reparatie.fac_usrdata_omschr AS gerepareerd,
          fac.safe_to_date (
                datum_reparatie.mld_kenmerkopdr_waarde
             || ' '
             || tijd_reparatie.mld_kenmerkopdr_waarde,
             'dd-mm-yyyy hh24:mi')
             AS datum_reparatie
     FROM mld_melding_object mo,
          mld_melding m,
          mld_opdr o,
          mld_statusopdr so,
          (SELECT *
             FROM mld_kenmerkopdr ko
            WHERE mld_kenmerk_key = 402) datum_uitg,
          (SELECT *
             FROM mld_kenmerkopdr ko
            WHERE mld_kenmerk_key = 403) tijd_uitg,
          (SELECT *
             FROM mld_kenmerkopdr ko, fac_usrdata ud
            WHERE     ko.mld_kenmerkopdr_waarde = ud.fac_usrdata_key
                  AND ud.fac_usrtab_key = 241
                  AND mld_kenmerk_key = 423) functieherstel,
          (SELECT *
             FROM mld_kenmerkopdr ko
            WHERE mld_kenmerk_key = 422) datum_functieherstel,
          (SELECT *
             FROM mld_kenmerkopdr ko
            WHERE mld_kenmerk_key = 425) tijd_functieherstel,
          (SELECT *
             FROM mld_kenmerkopdr ko, fac_usrdata ud
            WHERE     ko.mld_kenmerkopdr_waarde = ud.fac_usrdata_key
                  AND ud.fac_usrtab_key = 241
                  AND mld_kenmerk_key = 441) reparatie,
          (SELECT *
             FROM mld_kenmerkopdr ko
            WHERE mld_kenmerk_key = 427) datum_reparatie,
          (SELECT *
             FROM mld_kenmerkopdr ko
            WHERE mld_kenmerk_key = 428) tijd_reparatie
    WHERE     mo.mld_melding_key = m.mld_melding_key
          AND o.mld_melding_key = m.mld_melding_key
          AND o.mld_statusopdr_key = so.mld_statusopdr_key
          AND datum_uitg.mld_opdr_key = o.mld_opdr_key
          AND tijd_uitg.mld_opdr_key = o.mld_opdr_key
          AND functieherstel.mld_opdr_key(+) = o.mld_opdr_key
          AND datum_functieherstel.mld_opdr_key(+) = o.mld_opdr_key
          AND tijd_functieherstel.mld_opdr_key(+) = o.mld_opdr_key
          AND reparatie.mld_opdr_key(+) = o.mld_opdr_key
          AND datum_reparatie.mld_opdr_key(+) = o.mld_opdr_key
          AND tijd_reparatie.mld_opdr_key(+) = o.mld_opdr_key;
          
CREATE OR REPLACE VIEW hcas_v_rap_kpi
(
   locatie,
   bedrijf,
   pmode,
   service_window_van,
   service_window_tot,
   object_discipline,
   objectgroep,
   objectsoort,
   object,
   urgentieklasse_object,
   conditieklasse_object,
   type_melding,
   opdracht_key,
   opdracht_nr,
   datum_opdracht,
   functieherstel,
   max_functiehersteltijd,
   datum_functieherstel,
   functiehersteltijd_uren,
   gerepareerd,
   max_reparatietijd,
   datum_reparatie,
   reparatietijd_dgn,
   kpi_functieherstel,
   kpi_reparatie,
   kpi_one_time_fix
)
AS
   SELECT l.alg_locatie_omschrijving,
          kpi.prs_bedrijf_naam,
          DECODE (kpi.pmode, 1, 'Werkdagen', 0, 'Alle dagen'),
          kpi.geldend_fh_van AS service_window_van,
          kpi.geldend_fh_tot AS service_window_tot,
          obj.ins_discipline_omschrijving,
          obj.ins_srtgroep_omschrijving,
          obj.ins_srtdeel_omschrijving,
          kpi.ins_deel_omschrijving AS object,
          kpi.urgentieklasse,
          kpi.conditieklasse,
          type_mld.type_melding,
          o.mld_opdr_key,
          o.mld_opdr_key || '/' || mld_opdr_bedrijfopdr_volgnr as opdracht, 
          kpi.datum_uitgifte AS datum_opdracht,
          kpi.functieherstel,
          kpi.max_fh_tijd,
          kpi.datum_functieherstel,
          kpi.functiehersteltijd_uren,
          kpi.gerepareerd,
          kpi.max_rep_tijd,
          kpi.datum_reparatie,
          kpi.reparatietijd_dagen,
          CASE
             WHEN UPPER (functieherstel) = 'NEE'
             THEN
                'Niet van toepassing'
             WHEN (UPPER (functieherstel) = 'JA'
                   AND max_fh_tijd - functiehersteltijd_uren >= 0)
             THEN
                'Voldoende'
             WHEN (UPPER (functieherstel) = 'JA'
                   AND max_fh_tijd - functiehersteltijd_uren < 0)
             THEN
                'Onvoldoende '
             ELSE
                ''
          END
             AS KPI_functieherstel,
          CASE
             WHEN UPPER (gerepareerd) <> 'JA'
             THEN
                'Niet van toepassing'
             WHEN (UPPER (gerepareerd) = 'JA'
                   AND max_rep_tijd - reparatietijd_dagen >= 0)
             THEN
                'Voldoende'
             WHEN (UPPER (gerepareerd) = 'JA'
                   AND max_rep_tijd - reparatietijd_dagen < 0)
             THEN
                'Onvoldoende'
             ELSE
                ''
          END
             AS KPI_reparatie,
          CASE
             WHEN UPPER (functieherstel) = 'NEE'
                  OR datum_functieherstel = datum_reparatie
             THEN
                'Ja'
             ELSE
                'Nee '
          END
             AS KPI_one_time_fix
     FROM hcas_kpi_leveranciers kpi,
          mld_melding m,
          mld_opdr o,
          ins_v_deel_gegevens obj,
          alg_locatie l,
          (SELECT km.mld_melding_key, ud.fac_usrdata_omschr AS type_melding
             FROM mld_kenmerkmelding km, mld_kenmerk k, fac_usrdata ud
            WHERE k.mld_kenmerk_key = km.mld_kenmerk_key
                  AND k.mld_srtkenmerk_key = 181
                  AND fac.safe_to_number (mld_kenmerkmelding_waarde) =
                        ud.fac_usrdata_key
                  AND fac_usrtab_key = 121) type_mld
    WHERE     kpi.mld_melding_key = m.mld_melding_key
          AND kpi.ins_deel_key = obj.ins_deel_key
          AND kpi.mld_opdr_key = o.mld_opdr_key
          AND m.mld_alg_locatie_key = l.alg_locatie_key
          AND type_mld.mld_melding_key = m.mld_melding_key;      
       
CREATE OR REPLACE VIEW hcas_v_rap_kpi_one_time_fix
(
   locatie,
   bedrijf,
   type_melding,
   datum_uitgifte,
   aant_opdr,
   aant_one_time_fix
)
AS
     SELECT l.alg_locatie_omschrijving,
            kpi.prs_bedrijf_naam,
            type_mld.type_melding,
            kpi.datum_uitgifte,
            COUNT (kpi.mld_opdr_key),
            SUM(CASE
                   WHEN UPPER (functieherstel) = 'NEE'
                        OR datum_functieherstel = datum_reparatie
                   THEN
                      1
                   ELSE
                      0
                END)
       FROM hcas_kpi_leveranciers kpi,
            mld_melding m,
            ins_v_deel_gegevens obj,
            alg_locatie l,
            (SELECT km.mld_melding_key, ud.fac_usrdata_omschr AS type_melding
               FROM mld_kenmerkmelding km, mld_kenmerk k, fac_usrdata ud
              WHERE k.mld_kenmerk_key = km.mld_kenmerk_key
                    AND k.mld_srtkenmerk_key = 181
                    AND fac.safe_to_number (mld_kenmerkmelding_waarde) =
                          ud.fac_usrdata_key
                    AND fac_usrtab_key = 121) type_mld
      WHERE     kpi.mld_melding_key = m.mld_melding_key
            AND kpi.ins_deel_key = obj.ins_deel_key
            AND m.mld_alg_locatie_key = l.alg_locatie_key
            AND type_mld.mld_melding_key = m.mld_melding_key
   GROUP BY alg_locatie_omschrijving,
            prs_bedrijf_naam,
            type_melding,
            datum_uitgifte;

CREATE OR REPLACE VIEW hcas_v_rap_kpi_hhstoring
(
   locatie,
   bedrijf,
   type_melding,
   datum_opdracht,
   aant_opdr,
   aant_herh_storing
)
AS
  SELECT l.alg_locatie_omschrijving,
         prs_bedrijf_naam,
         type_melding,
         datum_uitgifte,
         COUNT (mld_opdr_key),
         SUM (DECODE (herhaalstoring, 'Ja', 1, 0))
    FROM hcas_kpi_leveranciers kpi,
         mld_melding m,
         alg_locatie l,
         (SELECT km.mld_melding_key, ud.fac_usrdata_omschr AS type_melding
            FROM mld_kenmerkmelding km, mld_kenmerk k, fac_usrdata ud
           WHERE k.mld_kenmerk_key = km.mld_kenmerk_key
                 AND k.mld_srtkenmerk_key = 181
                 AND fac.safe_to_number (mld_kenmerkmelding_waarde) =
                       ud.fac_usrdata_key
                 AND fac_usrtab_key = 121) type_mld
   WHERE     type_mld.mld_melding_key = kpi.mld_melding_key
         AND kpi.mld_melding_key = m.mld_melding_key
         AND m.mld_alg_locatie_key = l.alg_locatie_key
         AND type_mld.mld_melding_key = m.mld_melding_key
         AND kpi.conditieklasse NOT IN (5, 6)
GROUP BY l.alg_locatie_omschrijving,
         prs_bedrijf_naam,
         type_melding,
         datum_uitgifte;

CREATE OR REPLACE VIEW HCAS_V_RAP_KPI_DOWNTIME
(
   OPDRACHT,
   KWARTAAL,
   OBJECT_KEY,
   OBJECT_OMSCHRIJVING,
   LEVERANCIER,
   DATUM_UITGIFTE,
   DATUM_GEREED,
   MAX_UPTIME,
   DOWNTIME_DGN,
   UPTIME_DGN,
   TOELICHTING
)
AS
   -- Begin en eind in zelfde Q: Q - jaartal  datum uitgifte = Q - jaartal FH/reparatie
SELECT kpi.mld_opdr_key,
          TO_CHAR (COALESCE (kpi.datum_functieherstel, kpi.datum_reparatie),
                   'yyyy')
          || ' Q'
          || TO_CHAR (
                COALESCE (kpi.datum_functieherstel, kpi.datum_reparatie),
                'Q')
             AS tellend_kwartaal,
          kpi.ins_deel_key,
          kpi.ins_deel_omschrijving,
          kpi.prs_bedrijf_naam,
          kpi.datum_uitgifte,
          COALESCE (kpi.datum_functieherstel, kpi.datum_reparatie)
             datum_gereed,
          (ADD_MONTHS (TRUNC (datum_uitgifte, 'Q'), +3))
          - (TRUNC (datum_uitgifte, 'Q'))
             AS max_uptime,
          COALESCE (kpi.datum_functieherstel, kpi.datum_reparatie)
          - kpi.datum_uitgifte --- voor de downtime doen regime of urgentieklasse er niet toe
             downtime_dgn,
          ( (ADD_MONTHS (TRUNC (datum_uitgifte, 'Q'), +3))
           - (TRUNC (datum_uitgifte, 'Q')))
          - COALESCE (kpi.functiehersteltijd_dagen, kpi.reparatietijd_dagen)
             uptime_dgn,
          'Begin en einde in zelfde kwartaal' AS toelichting
     FROM hcas_kpi_leveranciers kpi
    WHERE 'Q'
          || TO_CHAR (
                COALESCE (kpi.datum_functieherstel, kpi.datum_reparatie),
                'Q')
          || ' '
          || TO_CHAR (
                COALESCE (kpi.datum_functieherstel, kpi.datum_reparatie),
                'yyyy') =
                'Q'
             || TO_CHAR (kpi.datum_uitgifte, 'Q')
             || ' '
             || TO_CHAR (kpi.datum_uitgifte, 'yyyy')  --- alleen afgeronde kwartalen gaan mee, dus einddatum ligt voor de begin datum van current Q
             AND (kpi.datum_functieherstel <  TRUNC(SYSDATE , 'Q')  OR kpi.datum_reparatie <  TRUNC(SYSDATE , 'Q') )
   UNION ALL 
   -- Begin en eind NIET in zelfde Q; het einde van de opdracht valt in een ander kwartaal, eerst het kwartaal tellen waar de aanmaak datum invalt
   -- De aanmaakdatum moet vallen in het laatste volledige kwartaal, dus aanmaakdatum < start huidig Q
   -- Let op: mld is nog niet per definitie afgemeld en zit dus niet persé in kpi tabel!
   SELECT kpi.mld_opdr_key,    -- Downtime is dan einddatum Q - datum uitgifte
             TO_CHAR (kpi.datum_uitgifte, 'yyyy')
          || ' Q'
          || TO_CHAR (kpi.datum_uitgifte, 'Q')
             AS tellend_kwartaal,                    
          kpi.ins_deel_key,
          kpi.ins_deel_omschrijving,
          kpi.prs_bedrijf_naam,
          kpi.datum_uitgifte,
          COALESCE (kpi.datum_functieherstel, kpi.datum_reparatie)
             datum_gereed,
          (ADD_MONTHS (TRUNC (datum_uitgifte, 'Q'), +3))
          - (TRUNC (datum_uitgifte, 'Q'))
             AS max_uptime,
          ADD_MONTHS (TRUNC (datum_uitgifte, 'Q'), +3) - kpi.datum_uitgifte --- voor de downtime doen regime of urgentieklasse er niet toe, einddatum is hier: einde kwartaal
             AS downtime_dgn,
          ( (ADD_MONTHS (TRUNC (datum_uitgifte, 'Q'), +3))
           - (TRUNC (datum_uitgifte, 'Q')))
          - (ADD_MONTHS (TRUNC (datum_uitgifte, 'Q'), +3)
             - kpi.datum_uitgifte)
             AS uptime_dgn,
          'Beginkwartaal tellen' AS toelichting
     FROM  (SELECT b.prs_bedrijf_key,
             b.prs_bedrijf_naam,                  
             onderhoud_obj.ins_deel_omschrijving,
             opdracht.ins_deel_key,        
             opdracht.mld_opdr_key,         
             opdracht.datum_uitgifte,
             opdracht.functieherstel,
             opdracht.datum_functieherstel,
             opdracht.gerepareerd,
             opdracht.datum_reparatie           
        FROM prs_bedrijf b,        
             (SELECT o.ins_deel_key,
                     o.ins_deel_omschrijving,
                     fac.safe_to_number (
                        onderhoudsleverancier.ins_kenmerkdeel_waarde)
                        AS prs_bedrijf_key                
                FROM ins_deel o,
                     (SELECT kd.*
                        FROM ins_kenmerkdeel kd, ins_kenmerk km
                       WHERE kd.ins_kenmerk_key = km.ins_kenmerk_key
                             AND km.ins_srtkenmerk_key = 62)
                     onderhoudsleverancier                    
               WHERE     o.ins_deel_verwijder IS NULL
                     AND onderhoudsleverancier.ins_deel_key = o.ins_deel_key )
             onderhoud_obj,
             (SELECT mo.ins_deel_key,
                     m.mld_melding_key,
                     o.mld_opdr_key,
                     o.mld_typeopdr_key,
                     o.mld_statusopdr_key,
                     so.mld_statusopdr_omschrijving,
                     fac.safe_to_number (o.mld_uitvoerende_keys)
                        AS uitv_bedrijf,
                     fac.safe_to_date (
                           datum_uitg.mld_kenmerkopdr_waarde
                        || ' '
                        || tijd_uitg.mld_kenmerkopdr_waarde,
                        'dd-mm-yyyy hh24:mi')
                        AS datum_uitgifte,
                     functieherstel.fac_usrdata_omschr AS functieherstel,
                     fac.safe_to_date (
                           datum_functieherstel.mld_kenmerkopdr_waarde
                        || ' '
                        || tijd_functieherstel.mld_kenmerkopdr_waarde,
                        'dd-mm-yyyy hh24:mi')
                        AS datum_functieherstel,
                     reparatie.fac_usrdata_omschr AS gerepareerd,
                     fac.safe_to_date (
                           datum_reparatie.mld_kenmerkopdr_waarde
                        || ' '
                        || tijd_reparatie.mld_kenmerkopdr_waarde,
                        'dd-mm-yyyy hh24:mi')
                        AS datum_reparatie
                FROM mld_melding_object mo,
                     mld_melding m,
                     mld_opdr o,
                     mld_statusopdr so,
                     (SELECT *
                        FROM mld_kenmerkopdr ko
                       WHERE mld_kenmerk_key = 402) datum_uitg,
                     (SELECT *
                        FROM mld_kenmerkopdr ko
                       WHERE mld_kenmerk_key = 403) tijd_uitg,
                     (SELECT *
                        FROM mld_kenmerkopdr ko, fac_usrdata ud
                       WHERE ko.mld_kenmerkopdr_waarde = ud.fac_usrdata_key
                             AND ud.fac_usrtab_key = 241
                             AND mld_kenmerk_key = 423) functieherstel,
                     (SELECT *
                        FROM mld_kenmerkopdr ko
                       WHERE mld_kenmerk_key = 422) datum_functieherstel,
                     (SELECT *
                        FROM mld_kenmerkopdr ko
                       WHERE mld_kenmerk_key = 425) tijd_functieherstel,
                     (SELECT *
                        FROM mld_kenmerkopdr ko, fac_usrdata ud
                       WHERE ko.mld_kenmerkopdr_waarde = ud.fac_usrdata_key
                             AND ud.fac_usrtab_key = 241
                             AND mld_kenmerk_key = 441) reparatie,
                     (SELECT *
                        FROM mld_kenmerkopdr ko
                       WHERE mld_kenmerk_key = 427) datum_reparatie,
                     (SELECT *
                        FROM mld_kenmerkopdr ko
                       WHERE mld_kenmerk_key = 428) tijd_reparatie                         
               WHERE     mo.mld_melding_key = m.mld_melding_key
                     AND o.mld_melding_key = m.mld_melding_key
                     AND o.mld_statusopdr_key = so.mld_statusopdr_key
                     AND datum_uitg.mld_opdr_key = o.mld_opdr_key
                     AND tijd_uitg.mld_opdr_key = o.mld_opdr_key
                     AND functieherstel.mld_opdr_key(+) = o.mld_opdr_key
                     AND datum_functieherstel.mld_opdr_key(+) =
                           o.mld_opdr_key
                     AND tijd_functieherstel.mld_opdr_key(+) = o.mld_opdr_key
                     AND reparatie.mld_opdr_key(+) = o.mld_opdr_key
                     AND datum_reparatie.mld_opdr_key(+) = o.mld_opdr_key                  
                     AND tijd_reparatie.mld_opdr_key(+) = o.mld_opdr_key)
             opdracht
       WHERE     prs_bedrijf_verwijder IS NULL
             AND prs_bedrijf_leverancier = 1      
             AND onderhoud_obj.prs_bedrijf_key = b.prs_bedrijf_key
             AND opdracht.uitv_bedrijf = b.prs_bedrijf_key
             AND opdracht.ins_deel_key = onderhoud_obj.ins_deel_key) kpi
    WHERE 'Q'
          || TO_CHAR (
                COALESCE (kpi.datum_functieherstel, kpi.datum_reparatie),
                'Q')
          || ' '
          || TO_CHAR (
                COALESCE (kpi.datum_functieherstel, kpi.datum_reparatie),
                'yyyy') <>
                'Q'
             || TO_CHAR (kpi.datum_uitgifte, 'Q')
             || ' '
             || TO_CHAR (kpi.datum_uitgifte, 'yyyy')
             AND   kpi.datum_uitgifte <  TRUNC(SYSDATE , 'Q')             
  UNION ALL 
   -- Begin en eind NIET in zelfde Q; het einde van de opdracht valt in een ander kwartaal, dan de uren tellen die vallen in het kwartaal van de afmeld datum
   -- De melding is dan al wel afgemeld, dus kan de KPI tabel gebruikt worden
   -- ook hier gaan we uit van het laatste volledige kwartaal dus datum functieherstel/ gereed < begin datum current Q
   SELECT kpi.mld_opdr_key, -- Downtime is dan datum FH/gereed - begindatum kwartaal
          TO_CHAR (COALESCE (kpi.datum_functieherstel, kpi.datum_reparatie),
                   'yyyy')
          || ' Q'
          || TO_CHAR (
                COALESCE (kpi.datum_functieherstel, kpi.datum_reparatie),
                'Q')
             AS tellend_kwartaal,
          kpi.ins_deel_key,
          kpi.ins_deel_omschrijving,
          kpi.prs_bedrijf_naam,
          kpi.datum_uitgifte,
          COALESCE (kpi.datum_functieherstel, kpi.datum_reparatie)
             datum_gereed,
          (ADD_MONTHS (
              TRUNC (
                 COALESCE (kpi.datum_functieherstel, kpi.datum_reparatie),
                 'Q'),
              +3))
          - (TRUNC (COALESCE (kpi.datum_functieherstel, kpi.datum_reparatie),
                    'Q'))
             AS max_uptime,
          COALESCE (kpi.datum_functieherstel, kpi.datum_reparatie)
          - TRUNC (COALESCE (kpi.datum_functieherstel, kpi.datum_reparatie),
                   'Q')
             AS downtime_dgn,
          ( (ADD_MONTHS (
                TRUNC (
                   COALESCE (kpi.datum_functieherstel, kpi.datum_reparatie),
                   'Q'),
                +3))
           - (TRUNC (
                 COALESCE (kpi.datum_functieherstel, kpi.datum_reparatie),
                 'Q')))
          - (COALESCE (kpi.datum_functieherstel, kpi.datum_reparatie)
             - TRUNC (
                  COALESCE (kpi.datum_functieherstel, kpi.datum_reparatie),
                  'Q'))
             AS uptime_dgn,
          'Eindkwartaal tellen' AS toelichting
     FROM hcas_kpi_leveranciers kpi
    WHERE 'Q'
          || TO_CHAR (
                COALESCE (kpi.datum_functieherstel, kpi.datum_reparatie),
                'Q')
          || ' '
          || TO_CHAR (
                COALESCE (kpi.datum_functieherstel, kpi.datum_reparatie),
                'yyyy') <>
                'Q'
             || TO_CHAR (kpi.datum_uitgifte, 'Q')
             || ' '
             || TO_CHAR (kpi.datum_uitgifte, 'yyyy')
             AND (kpi.datum_functieherstel <  TRUNC(SYSDATE , 'Q')  OR kpi.datum_reparatie <  TRUNC(SYSDATE , 'Q') )
   UNION ALL
   -- Begin en eind NIET in zelfde Q of volgend Q: dan zijn er dus tussenliggende kwartalen met 100% downtime
   -- Dit zijn dus uiitsluitend de meldingen die over meer dan 2 kwartalen gaan
   -- Downtime is dan gelijk aan max. uptime
   -- Dus: datum gereed > einddatum next Q kwartaal uitgifte, de opdracht heeft het gehele volgende kwartaal open gestaan.
   -- Of : datum gereed is null op tellend kwartaal (Q waarin de melding is aangemaakt + resp. 1, 2, 3 of 4)
SELECT kpi.mld_opdr_key,    
          TO_CHAR ( (ADD_MONTHS (TRUNC (datum_uitgifte, 'Q'), 3)), 'yyyy')
       || ' Q'
       || TO_CHAR ( (ADD_MONTHS (TRUNC (datum_uitgifte, 'Q'), 3)), 'Q')
          AS tellend_kwartaal,
       kpi.ins_deel_key,
       kpi.ins_deel_omschrijving,
       kpi.prs_bedrijf_naam,
       kpi.datum_uitgifte,
       COALESCE (kpi.datum_functieherstel, kpi.datum_reparatie) datum_gereed,
       ADD_MONTHS (TRUNC (datum_uitgifte, 'Q'), 6)
       - ADD_MONTHS (TRUNC (datum_uitgifte, 'Q'), 3)
          MAX_UPTIME,
       ADD_MONTHS (TRUNC (datum_uitgifte, 'Q'), 6)
       - ADD_MONTHS (TRUNC (datum_uitgifte, 'Q'), 3) 
          DOWNTIME_DGN,
       0 UPTIME,
       'Eerste volledige kwartaal down' AS toelichting
  FROM (SELECT b.prs_bedrijf_key,
               b.prs_bedrijf_naam,
               onderhoud_obj.ins_deel_omschrijving,
               opdracht.ins_deel_key,
               opdracht.mld_opdr_key,
               opdracht.datum_uitgifte,
               opdracht.functieherstel,
               opdracht.datum_functieherstel,
               opdracht.gerepareerd,
               opdracht.datum_reparatie
          FROM prs_bedrijf b,
               (SELECT o.ins_deel_key,
                       o.ins_deel_omschrijving,
                       fac.safe_to_number (
                          onderhoudsleverancier.ins_kenmerkdeel_waarde)
                          AS prs_bedrijf_key
                  FROM ins_deel o,
                       (SELECT kd.*
                          FROM ins_kenmerkdeel kd, ins_kenmerk km
                         WHERE kd.ins_kenmerk_key = km.ins_kenmerk_key
                               AND km.ins_srtkenmerk_key = 62)
                       onderhoudsleverancier
                 WHERE o.ins_deel_verwijder IS NULL
                       AND onderhoudsleverancier.ins_deel_key =
                             o.ins_deel_key) onderhoud_obj,
               (SELECT mo.ins_deel_key,
                       m.mld_melding_key,
                       o.mld_opdr_key,
                       o.mld_typeopdr_key,
                       o.mld_statusopdr_key,
                       so.mld_statusopdr_omschrijving,
                       fac.safe_to_number (o.mld_uitvoerende_keys)
                          AS uitv_bedrijf,
                       fac.safe_to_date (
                             datum_uitg.mld_kenmerkopdr_waarde
                          || ' '
                          || tijd_uitg.mld_kenmerkopdr_waarde,
                          'dd-mm-yyyy hh24:mi')
                          AS datum_uitgifte,
                       functieherstel.fac_usrdata_omschr AS functieherstel,
                       fac.safe_to_date (
                             datum_functieherstel.mld_kenmerkopdr_waarde
                          || ' '
                          || tijd_functieherstel.mld_kenmerkopdr_waarde,
                          'dd-mm-yyyy hh24:mi')
                          AS datum_functieherstel,
                       reparatie.fac_usrdata_omschr AS gerepareerd,
                       fac.safe_to_date (
                             datum_reparatie.mld_kenmerkopdr_waarde
                          || ' '
                          || tijd_reparatie.mld_kenmerkopdr_waarde,
                          'dd-mm-yyyy hh24:mi')
                          AS datum_reparatie
                  FROM mld_melding_object mo,
                       mld_melding m,
                       mld_opdr o,
                       mld_statusopdr so,
                       (SELECT *
                          FROM mld_kenmerkopdr ko
                         WHERE mld_kenmerk_key = 402) datum_uitg,
                       (SELECT *
                          FROM mld_kenmerkopdr ko
                         WHERE mld_kenmerk_key = 403) tijd_uitg,
                       (SELECT *
                          FROM mld_kenmerkopdr ko, fac_usrdata ud
                         WHERE ko.mld_kenmerkopdr_waarde = ud.fac_usrdata_key
                               AND ud.fac_usrtab_key = 241
                               AND mld_kenmerk_key = 423) functieherstel,
                       (SELECT *
                          FROM mld_kenmerkopdr ko
                         WHERE mld_kenmerk_key = 422) datum_functieherstel,
                       (SELECT *
                          FROM mld_kenmerkopdr ko
                         WHERE mld_kenmerk_key = 425) tijd_functieherstel,
                       (SELECT *
                          FROM mld_kenmerkopdr ko, fac_usrdata ud
                         WHERE ko.mld_kenmerkopdr_waarde = ud.fac_usrdata_key
                               AND ud.fac_usrtab_key = 241
                               AND mld_kenmerk_key = 441) reparatie,
                       (SELECT *
                          FROM mld_kenmerkopdr ko
                         WHERE mld_kenmerk_key = 427) datum_reparatie,
                       (SELECT *
                          FROM mld_kenmerkopdr ko
                         WHERE mld_kenmerk_key = 428) tijd_reparatie
                 WHERE     mo.mld_melding_key = m.mld_melding_key
                       AND o.mld_melding_key = m.mld_melding_key
                       AND o.mld_statusopdr_key = so.mld_statusopdr_key
                       AND datum_uitg.mld_opdr_key = o.mld_opdr_key
                       AND tijd_uitg.mld_opdr_key = o.mld_opdr_key
                       AND functieherstel.mld_opdr_key(+) = o.mld_opdr_key
                       AND datum_functieherstel.mld_opdr_key(+) =
                             o.mld_opdr_key
                       AND tijd_functieherstel.mld_opdr_key(+) =
                             o.mld_opdr_key
                       AND reparatie.mld_opdr_key(+) = o.mld_opdr_key
                       AND datum_reparatie.mld_opdr_key(+) = o.mld_opdr_key
                       AND tijd_reparatie.mld_opdr_key(+) = o.mld_opdr_key)
               opdracht
         WHERE     prs_bedrijf_verwijder IS NULL
               AND prs_bedrijf_leverancier = 1
               AND onderhoud_obj.prs_bedrijf_key = b.prs_bedrijf_key
               AND opdracht.uitv_bedrijf = b.prs_bedrijf_key
               AND opdracht.ins_deel_key = onderhoud_obj.ins_deel_key) kpi
 WHERE ( (COALESCE (kpi.datum_functieherstel, kpi.datum_reparatie) >
             LAST_DAY (ADD_MONTHS (TRUNC (datum_uitgifte, 'Q'), 5)))
        OR (kpi.datum_functieherstel IS NULL AND kpi.datum_reparatie IS NULL))
       AND LAST_DAY (ADD_MONTHS (TRUNC (datum_uitgifte, 'Q'), 5)) < SYSDATE
UNION ALL
-- Datum gereed > einddatum 2 kwartalen verder, de opdracht heeft 2 gehele volgende kwartalen open gestaan.
SELECT kpi.mld_opdr_key,   
          TO_CHAR ( (ADD_MONTHS (TRUNC (datum_uitgifte, 'Q'), 6)), 'yyyy')
       || ' Q'
       || TO_CHAR ( (ADD_MONTHS (TRUNC (datum_uitgifte, 'Q'), 6)), 'Q')
          AS tellend_kwartaal, 
       kpi.ins_deel_key,
       kpi.ins_deel_omschrijving,
       kpi.prs_bedrijf_naam,
       kpi.datum_uitgifte,
       COALESCE (kpi.datum_functieherstel, kpi.datum_reparatie) datum_gereed,
       ADD_MONTHS (TRUNC (datum_uitgifte, 'Q'), 9)
       - ADD_MONTHS (TRUNC (datum_uitgifte, 'Q'), 6)
          MAX_UPTIME,
       ADD_MONTHS (TRUNC (datum_uitgifte, 'Q'), 9)
       - ADD_MONTHS (TRUNC (datum_uitgifte, 'Q'), 6) 
          DOWNTIME_DGN,
       0 UPTIME,
       'Tweede Kwartaal volledige down' AS toelichting
  FROM (SELECT b.prs_bedrijf_key,
               b.prs_bedrijf_naam,
               onderhoud_obj.ins_deel_omschrijving,
               opdracht.ins_deel_key,
               opdracht.mld_opdr_key,
               opdracht.datum_uitgifte,
               opdracht.functieherstel,
               opdracht.datum_functieherstel,
               opdracht.gerepareerd,
               opdracht.datum_reparatie
          FROM prs_bedrijf b,
               (SELECT o.ins_deel_key,
                       o.ins_deel_omschrijving,
                       fac.safe_to_number (
                          onderhoudsleverancier.ins_kenmerkdeel_waarde)
                          AS prs_bedrijf_key
                  FROM ins_deel o,
                       (SELECT kd.*
                          FROM ins_kenmerkdeel kd, ins_kenmerk km
                         WHERE kd.ins_kenmerk_key = km.ins_kenmerk_key
                               AND km.ins_srtkenmerk_key = 62)
                       onderhoudsleverancier
                 WHERE o.ins_deel_verwijder IS NULL
                       AND onderhoudsleverancier.ins_deel_key =
                             o.ins_deel_key) onderhoud_obj,
               (SELECT mo.ins_deel_key,
                       m.mld_melding_key,
                       o.mld_opdr_key,
                       o.mld_typeopdr_key,
                       o.mld_statusopdr_key,
                       so.mld_statusopdr_omschrijving,
                       fac.safe_to_number (o.mld_uitvoerende_keys)
                          AS uitv_bedrijf,
                       fac.safe_to_date (
                             datum_uitg.mld_kenmerkopdr_waarde
                          || ' '
                          || tijd_uitg.mld_kenmerkopdr_waarde,
                          'dd-mm-yyyy hh24:mi')
                          AS datum_uitgifte,
                       functieherstel.fac_usrdata_omschr AS functieherstel,
                       fac.safe_to_date (
                             datum_functieherstel.mld_kenmerkopdr_waarde
                          || ' '
                          || tijd_functieherstel.mld_kenmerkopdr_waarde,
                          'dd-mm-yyyy hh24:mi')
                          AS datum_functieherstel,
                       reparatie.fac_usrdata_omschr AS gerepareerd,
                       fac.safe_to_date (
                             datum_reparatie.mld_kenmerkopdr_waarde
                          || ' '
                          || tijd_reparatie.mld_kenmerkopdr_waarde,
                          'dd-mm-yyyy hh24:mi')
                          AS datum_reparatie
                  FROM mld_melding_object mo,
                       mld_melding m,
                       mld_opdr o,
                       mld_statusopdr so,
                       (SELECT *
                          FROM mld_kenmerkopdr ko
                         WHERE mld_kenmerk_key = 402) datum_uitg,
                       (SELECT *
                          FROM mld_kenmerkopdr ko
                         WHERE mld_kenmerk_key = 403) tijd_uitg,
                       (SELECT *
                          FROM mld_kenmerkopdr ko, fac_usrdata ud
                         WHERE ko.mld_kenmerkopdr_waarde = ud.fac_usrdata_key
                               AND ud.fac_usrtab_key = 241
                               AND mld_kenmerk_key = 423) functieherstel,
                       (SELECT *
                          FROM mld_kenmerkopdr ko
                         WHERE mld_kenmerk_key = 422) datum_functieherstel,
                       (SELECT *
                          FROM mld_kenmerkopdr ko
                         WHERE mld_kenmerk_key = 425) tijd_functieherstel,
                       (SELECT *
                          FROM mld_kenmerkopdr ko, fac_usrdata ud
                         WHERE ko.mld_kenmerkopdr_waarde = ud.fac_usrdata_key
                               AND ud.fac_usrtab_key = 241
                               AND mld_kenmerk_key = 441) reparatie,
                       (SELECT *
                          FROM mld_kenmerkopdr ko
                         WHERE mld_kenmerk_key = 427) datum_reparatie,
                       (SELECT *
                          FROM mld_kenmerkopdr ko
                         WHERE mld_kenmerk_key = 428) tijd_reparatie
                 WHERE     mo.mld_melding_key = m.mld_melding_key
                       AND o.mld_melding_key = m.mld_melding_key
                       AND o.mld_statusopdr_key = so.mld_statusopdr_key
                       AND datum_uitg.mld_opdr_key = o.mld_opdr_key
                       AND tijd_uitg.mld_opdr_key = o.mld_opdr_key
                       AND functieherstel.mld_opdr_key(+) = o.mld_opdr_key
                       AND datum_functieherstel.mld_opdr_key(+) =
                             o.mld_opdr_key
                       AND tijd_functieherstel.mld_opdr_key(+) =
                             o.mld_opdr_key
                       AND reparatie.mld_opdr_key(+) = o.mld_opdr_key
                       AND datum_reparatie.mld_opdr_key(+) = o.mld_opdr_key
                       AND tijd_reparatie.mld_opdr_key(+) = o.mld_opdr_key)
               opdracht
         WHERE     prs_bedrijf_verwijder IS NULL
               AND prs_bedrijf_leverancier = 1
               AND onderhoud_obj.prs_bedrijf_key = b.prs_bedrijf_key
               AND opdracht.uitv_bedrijf = b.prs_bedrijf_key
               AND opdracht.ins_deel_key = onderhoud_obj.ins_deel_key) kpi
 WHERE (COALESCE (kpi.datum_functieherstel, kpi.datum_reparatie) >
           LAST_DAY (ADD_MONTHS (TRUNC (datum_uitgifte, 'Q'), 8))
        OR (kpi.datum_functieherstel IS NULL AND kpi.datum_reparatie IS NULL))
       AND LAST_DAY (ADD_MONTHS (TRUNC (datum_uitgifte, 'Q'), 8)) < SYSDATE
UNION ALL
-- Datum gereed > einddatum 3 kwartalen verder, de opdracht heeft 3 gehele volgende kwartalen open gestaan.
SELECT kpi.mld_opdr_key, 
          TO_CHAR ( (ADD_MONTHS (TRUNC (datum_uitgifte, 'Q'), 9)), 'yyyy')
       || ' Q'
       || TO_CHAR ( (ADD_MONTHS (TRUNC (datum_uitgifte, 'Q'), 9)), 'Q') 
          AS TELLEND_KWARTAAL,
       kpi.ins_deel_key,
       kpi.ins_deel_omschrijving,
       kpi.prs_bedrijf_naam,
       kpi.datum_uitgifte,
       COALESCE (kpi.datum_functieherstel, kpi.datum_reparatie) datum_gereed,
       ADD_MONTHS (TRUNC (datum_uitgifte, 'Q'), 12)
       - ADD_MONTHS (TRUNC (datum_uitgifte, 'Q'), 9)
          MAX_UPTIME,
       ADD_MONTHS (TRUNC (datum_uitgifte, 'Q'), 12)
       - ADD_MONTHS (TRUNC (datum_uitgifte, 'Q'), 9)
          DOWNTIME_DGN,
       0 UPTIME,
       'Derde kwartaal volledig down' AS toelichting
  FROM (SELECT b.prs_bedrijf_key,
               b.prs_bedrijf_naam,
               onderhoud_obj.ins_deel_omschrijving,
               opdracht.ins_deel_key,
               opdracht.mld_opdr_key,
               opdracht.datum_uitgifte,
               opdracht.functieherstel,
               opdracht.datum_functieherstel,
               opdracht.gerepareerd,
               opdracht.datum_reparatie
          FROM prs_bedrijf b,
               (SELECT o.ins_deel_key,
                       o.ins_deel_omschrijving,
                       fac.safe_to_number (
                          onderhoudsleverancier.ins_kenmerkdeel_waarde)
                          AS prs_bedrijf_key
                  FROM ins_deel o,
                       (SELECT kd.*
                          FROM ins_kenmerkdeel kd, ins_kenmerk km
                         WHERE kd.ins_kenmerk_key = km.ins_kenmerk_key
                               AND km.ins_srtkenmerk_key = 62)
                       onderhoudsleverancier
                 WHERE o.ins_deel_verwijder IS NULL
                       AND onderhoudsleverancier.ins_deel_key =
                             o.ins_deel_key) onderhoud_obj,
               (SELECT mo.ins_deel_key,
                       m.mld_melding_key,
                       o.mld_opdr_key,
                       o.mld_typeopdr_key,
                       o.mld_statusopdr_key,
                       so.mld_statusopdr_omschrijving,
                       fac.safe_to_number (o.mld_uitvoerende_keys)
                          AS uitv_bedrijf,
                       fac.safe_to_date (
                             datum_uitg.mld_kenmerkopdr_waarde
                          || ' '
                          || tijd_uitg.mld_kenmerkopdr_waarde,
                          'dd-mm-yyyy hh24:mi')
                          AS datum_uitgifte,
                       functieherstel.fac_usrdata_omschr AS functieherstel,
                       fac.safe_to_date (
                             datum_functieherstel.mld_kenmerkopdr_waarde
                          || ' '
                          || tijd_functieherstel.mld_kenmerkopdr_waarde,
                          'dd-mm-yyyy hh24:mi')
                          AS datum_functieherstel,
                       reparatie.fac_usrdata_omschr AS gerepareerd,
                       fac.safe_to_date (
                             datum_reparatie.mld_kenmerkopdr_waarde
                          || ' '
                          || tijd_reparatie.mld_kenmerkopdr_waarde,
                          'dd-mm-yyyy hh24:mi')
                          AS datum_reparatie
                  FROM mld_melding_object mo,
                       mld_melding m,
                       mld_opdr o,
                       mld_statusopdr so,
                       (SELECT *
                          FROM mld_kenmerkopdr ko
                         WHERE mld_kenmerk_key = 402) datum_uitg,
                       (SELECT *
                          FROM mld_kenmerkopdr ko
                         WHERE mld_kenmerk_key = 403) tijd_uitg,
                       (SELECT *
                          FROM mld_kenmerkopdr ko, fac_usrdata ud
                         WHERE ko.mld_kenmerkopdr_waarde = ud.fac_usrdata_key
                               AND ud.fac_usrtab_key = 241
                               AND mld_kenmerk_key = 423) functieherstel,
                       (SELECT *
                          FROM mld_kenmerkopdr ko
                         WHERE mld_kenmerk_key = 422) datum_functieherstel,
                       (SELECT *
                          FROM mld_kenmerkopdr ko
                         WHERE mld_kenmerk_key = 425) tijd_functieherstel,
                       (SELECT *
                          FROM mld_kenmerkopdr ko, fac_usrdata ud
                         WHERE ko.mld_kenmerkopdr_waarde = ud.fac_usrdata_key
                               AND ud.fac_usrtab_key = 241
                               AND mld_kenmerk_key = 441) reparatie,
                       (SELECT *
                          FROM mld_kenmerkopdr ko
                         WHERE mld_kenmerk_key = 427) datum_reparatie,
                       (SELECT *
                          FROM mld_kenmerkopdr ko
                         WHERE mld_kenmerk_key = 428) tijd_reparatie
                 WHERE     mo.mld_melding_key = m.mld_melding_key
                       AND o.mld_melding_key = m.mld_melding_key
                       AND o.mld_statusopdr_key = so.mld_statusopdr_key
                       AND datum_uitg.mld_opdr_key = o.mld_opdr_key
                       AND tijd_uitg.mld_opdr_key = o.mld_opdr_key
                       AND functieherstel.mld_opdr_key(+) = o.mld_opdr_key
                       AND datum_functieherstel.mld_opdr_key(+) =
                             o.mld_opdr_key
                       AND tijd_functieherstel.mld_opdr_key(+) =
                             o.mld_opdr_key
                       AND reparatie.mld_opdr_key(+) = o.mld_opdr_key
                       AND datum_reparatie.mld_opdr_key(+) = o.mld_opdr_key
                       AND tijd_reparatie.mld_opdr_key(+) = o.mld_opdr_key)
               opdracht
         WHERE     prs_bedrijf_verwijder IS NULL
               AND prs_bedrijf_leverancier = 1
               AND onderhoud_obj.prs_bedrijf_key = b.prs_bedrijf_key
               AND opdracht.uitv_bedrijf = b.prs_bedrijf_key
               AND opdracht.ins_deel_key = onderhoud_obj.ins_deel_key) kpi
 WHERE (COALESCE (kpi.datum_functieherstel, kpi.datum_reparatie) >
           LAST_DAY (ADD_MONTHS (TRUNC (datum_uitgifte, 'Q'), 11))
        OR (kpi.datum_functieherstel IS NULL AND kpi.datum_reparatie IS NULL))
       AND LAST_DAY (ADD_MONTHS (TRUNC (datum_uitgifte, 'Q'), 11)) < SYSDATE
UNION ALL
-- De opdracht heeft 4 gehele volgende kwartalen/ een volledig jaar open gestaan.
SELECT kpi.mld_opdr_key,    
          TO_CHAR ( (ADD_MONTHS (TRUNC (datum_uitgifte, 'Q'), 12)), 'yyyy')
       || ' Q'
       || TO_CHAR ( (ADD_MONTHS (TRUNC (datum_uitgifte, 'Q'), 12)), 'Q')
          AS TELLEND_KWARTAAL,
       kpi.ins_deel_key,
       kpi.ins_deel_omschrijving,
       kpi.prs_bedrijf_naam,
       kpi.datum_uitgifte,
       COALESCE (kpi.datum_functieherstel, kpi.datum_reparatie) datum_gereed,
       ADD_MONTHS (TRUNC (datum_uitgifte, 'Q'), 15)
       - ADD_MONTHS (TRUNC (datum_uitgifte, 'Q'), 12)
          MAX_UPTIME,
       ADD_MONTHS (TRUNC (datum_uitgifte, 'Q'), 15)
       - ADD_MONTHS (TRUNC (datum_uitgifte, 'Q'), 12)
          DOWNTIME_DGN,
       0 UPTIME,
       'Vierde kwartaal volledig down' AS omschrijving
  FROM (SELECT b.prs_bedrijf_key,
               b.prs_bedrijf_naam,
               onderhoud_obj.ins_deel_omschrijving,
               opdracht.ins_deel_key,
               opdracht.mld_opdr_key,
               opdracht.datum_uitgifte,
               opdracht.functieherstel,
               opdracht.datum_functieherstel,
               opdracht.gerepareerd,
               opdracht.datum_reparatie
          FROM prs_bedrijf b,
               (SELECT o.ins_deel_key,
                       o.ins_deel_omschrijving,
                       fac.safe_to_number (
                          onderhoudsleverancier.ins_kenmerkdeel_waarde)
                          AS prs_bedrijf_key
                  FROM ins_deel o,
                       (SELECT kd.*
                          FROM ins_kenmerkdeel kd, ins_kenmerk km
                         WHERE kd.ins_kenmerk_key = km.ins_kenmerk_key
                               AND km.ins_srtkenmerk_key = 62)
                       onderhoudsleverancier
                 WHERE o.ins_deel_verwijder IS NULL
                       AND onderhoudsleverancier.ins_deel_key =
                             o.ins_deel_key) onderhoud_obj,
               (SELECT mo.ins_deel_key,
                       m.mld_melding_key,
                       o.mld_opdr_key,
                       o.mld_typeopdr_key,
                       o.mld_statusopdr_key,
                       so.mld_statusopdr_omschrijving,
                       fac.safe_to_number (o.mld_uitvoerende_keys)
                          AS uitv_bedrijf,
                       fac.safe_to_date (
                             datum_uitg.mld_kenmerkopdr_waarde
                          || ' '
                          || tijd_uitg.mld_kenmerkopdr_waarde,
                          'dd-mm-yyyy hh24:mi')
                          AS datum_uitgifte,
                       functieherstel.fac_usrdata_omschr AS functieherstel,
                       fac.safe_to_date (
                             datum_functieherstel.mld_kenmerkopdr_waarde
                          || ' '
                          || tijd_functieherstel.mld_kenmerkopdr_waarde,
                          'dd-mm-yyyy hh24:mi')
                          AS datum_functieherstel,
                       reparatie.fac_usrdata_omschr AS gerepareerd,
                       fac.safe_to_date (
                             datum_reparatie.mld_kenmerkopdr_waarde
                          || ' '
                          || tijd_reparatie.mld_kenmerkopdr_waarde,
                          'dd-mm-yyyy hh24:mi')
                          AS datum_reparatie
                  FROM mld_melding_object mo,
                       mld_melding m,
                       mld_opdr o,
                       mld_statusopdr so,
                       (SELECT *
                          FROM mld_kenmerkopdr ko
                         WHERE mld_kenmerk_key = 402) datum_uitg,
                       (SELECT *
                          FROM mld_kenmerkopdr ko
                         WHERE mld_kenmerk_key = 403) tijd_uitg,
                       (SELECT *
                          FROM mld_kenmerkopdr ko, fac_usrdata ud
                         WHERE ko.mld_kenmerkopdr_waarde = ud.fac_usrdata_key
                               AND ud.fac_usrtab_key = 241
                               AND mld_kenmerk_key = 423) functieherstel,
                       (SELECT *
                          FROM mld_kenmerkopdr ko
                         WHERE mld_kenmerk_key = 422) datum_functieherstel,
                       (SELECT *
                          FROM mld_kenmerkopdr ko
                         WHERE mld_kenmerk_key = 425) tijd_functieherstel,
                       (SELECT *
                          FROM mld_kenmerkopdr ko, fac_usrdata ud
                         WHERE ko.mld_kenmerkopdr_waarde = ud.fac_usrdata_key
                               AND ud.fac_usrtab_key = 241
                               AND mld_kenmerk_key = 441) reparatie,
                       (SELECT *
                          FROM mld_kenmerkopdr ko
                         WHERE mld_kenmerk_key = 427) datum_reparatie,
                       (SELECT *
                          FROM mld_kenmerkopdr ko
                         WHERE mld_kenmerk_key = 428) tijd_reparatie
                 WHERE     mo.mld_melding_key = m.mld_melding_key
                       AND o.mld_melding_key = m.mld_melding_key
                       AND o.mld_statusopdr_key = so.mld_statusopdr_key
                       AND datum_uitg.mld_opdr_key = o.mld_opdr_key
                       AND tijd_uitg.mld_opdr_key = o.mld_opdr_key
                       AND functieherstel.mld_opdr_key(+) = o.mld_opdr_key
                       AND datum_functieherstel.mld_opdr_key(+) =
                             o.mld_opdr_key
                       AND tijd_functieherstel.mld_opdr_key(+) =
                             o.mld_opdr_key
                       AND reparatie.mld_opdr_key(+) = o.mld_opdr_key
                       AND datum_reparatie.mld_opdr_key(+) = o.mld_opdr_key
                       AND tijd_reparatie.mld_opdr_key(+) = o.mld_opdr_key)
               opdracht
         WHERE     prs_bedrijf_verwijder IS NULL
               AND prs_bedrijf_leverancier = 1
               AND onderhoud_obj.prs_bedrijf_key = b.prs_bedrijf_key
               AND opdracht.uitv_bedrijf = b.prs_bedrijf_key
               AND opdracht.ins_deel_key = onderhoud_obj.ins_deel_key) kpi
 WHERE (COALESCE (kpi.datum_functieherstel, kpi.datum_reparatie) >
           LAST_DAY (ADD_MONTHS (TRUNC (datum_uitgifte, 'Q'), 14))
        OR (kpi.datum_functieherstel IS NULL AND kpi.datum_reparatie IS NULL))
       AND LAST_DAY (ADD_MONTHS (TRUNC (datum_uitgifte, 'Q'), 14)) < SYSDATE;
        
---- ===================================================
--- Views tbv de FM dashboard 
--- HCAS#54956 Alles op Groen 

--- Operationeel Trends 
--- Resultaatgebied 2: Gem. doorlooptijd meldingen per locatie per meldingcategorie
CREATE OR REPLACE VIEW HCAS_V_TRENDS_RESG2
AS
  SELECT l.alg_locatie_omschrijving,
         vg.ins_discipline_omschrijving,
            TO_CHAR (m.mld_melding_einddatum, 'YYYY')
         || ' / '
         || TO_CHAR (m.mld_melding_einddatum, 'mm')
            AS periode,
         (SUM (m.mld_melding_einddatum - m.mld_melding_datum))
         / (COUNT (m.mld_melding_key))
            AS gem_doorlooptijd
    FROM mld_melding m,
         mld_stdmelding sm,
         ins_tab_discipline vg,
         alg_locatie l
   WHERE     m.mld_melding_status IN (5, 6) --- status is afgemeld of historie
         AND m.mld_stdmelding_key = sm.mld_stdmelding_key
         AND sm.mld_ins_discipline_key = vg.ins_discipline_key
         AND m.mld_alg_locatie_key = l.alg_locatie_key
         AND m.mld_melding_einddatum > TO_DATE ('01-01-2000', 'dd-mm-yyyy')
         AND MONTHS_BETWEEN (TRUNC (TRUNC (SYSDATE, 'Month'), 'Month'),
                             m.mld_melding_datum) < 12
         AND MONTHS_BETWEEN (TRUNC (TRUNC (SYSDATE, 'Month'), 'Month'),
                             m.mld_melding_datum) > 0
GROUP BY l.alg_locatie_omschrijving,
         vg.ins_discipline_omschrijving,
            TO_CHAR (m.mld_melding_einddatum, 'YYYY')
         || ' / '
         || TO_CHAR (m.mld_melding_einddatum, 'mm')
ORDER BY l.alg_locatie_omschrijving,
         vg.ins_discipline_omschrijving,
            TO_CHAR (m.mld_melding_einddatum, 'YYYY')
         || ' / '
         || TO_CHAR (m.mld_melding_einddatum, 'mm');        

--- Operationeel Trends 
--- Resultaatgebied 3: Gem. uptime apparaten per vestiging
CREATE OR REPLACE VIEW HCAS_V_TRENDS_RESG3
AS
  SELECT objecten.periode,
         objecten.locatie,
         objecten.max_dgn * COUNT (objecten.ins_deel_key) max_uptime,
         COUNT (objecten.ins_deel_key) aant_obj,
         SUM (nvl(storingen.downtime,0)) downtime,
         (objecten.max_dgn * COUNT (objecten.ins_deel_key)) - SUM (nvl(storingen.downtime,0)) uptime,
        ( ( (objecten.max_dgn * COUNT (objecten.ins_deel_key)) - SUM (nvl(storingen.downtime,0)) ) / ( objecten.max_dgn * COUNT (objecten.ins_deel_key) )) *100 perc_uptime
    FROM    (SELECT    TO_CHAR (periode.begin_mnd, 'YYYY')
                    || ' / '
                    || TO_CHAR (periode.begin_mnd, 'mm')
                       AS periode,
                    eind_mnd - begin_mnd max_dgn,
                    l.alg_locatie_omschrijving locatie,
                    o.ins_deel_key
               FROM (    SELECT ADD_MONTHS (TRUNC (SYSDATE, 'MM'), -1 * ROWNUM)
                                   begin_mnd,
                                LAST_DAY (
                                   ADD_MONTHS (TRUNC (SYSDATE, 'MM'), -1 * ROWNUM))
                                   eind_mnd
                           FROM DUAL
                     CONNECT BY LEVEL <= 12) periode,
                    ins_deel o,
                    alg_locatie l
              WHERE o.ins_alg_locatie_key = l.alg_locatie_key
                    AND o.ins_deel_aanmaak < periode.begin_mnd
                    AND (o.ins_deel_verwijder > periode.eind_mnd
                         OR o.ins_deel_verwijder IS NULL)
                    AND (o.ins_deel_vervaldatum > periode.eind_mnd
                         OR o.ins_deel_vervaldatum IS NULL)) objecten
         LEFT OUTER JOIN
            (SELECT    TO_CHAR (periode.begin_mnd, 'YYYY')
                    || ' / '
                    || TO_CHAR (periode.begin_mnd, 'mm')
                       AS periode,
                    (eind_mnd - begin_mnd) max_dgn,
                    mo.ins_deel_key,
                    CASE
                       --- scenario 1: begin en eind van de melding vallen in dezelfde maand
                    WHEN (mld_melding_datum > begin_mnd
                          AND mld_melding_einddatum < eind_mnd)
                       THEN
                          mld_melding_einddatum - mld_melding_datum
                       --- scenario 2: begin van de melding valt binnen de maand maar het einde niet
                    WHEN (mld_melding_datum >= begin_mnd
                          AND mld_melding_einddatum > eind_mnd)
                       THEN
                          eind_mnd - mld_melding_datum
                       --- scenario 3: begin en einde van de melding vallen buiten de maand, dan is de downtime gewoon de max
                    WHEN (mld_melding_datum < begin_mnd
                          AND mld_melding_einddatum > eind_mnd)
                       THEN
                          eind_mnd - begin_mnd
                       --- scenario 4: meldingdatum ligt voor het begin van de maand maar de einddatum valt wel in de maand
                    ELSE
                          mld_melding_einddatum - begin_mnd
                    END
                       AS downtime,
                    m.mld_melding_key,
                    mld_melding_datum,
                    mld_melding_einddatum,
                    vg.ins_discipline_omschrijving
               FROM (    SELECT ADD_MONTHS (TRUNC (SYSDATE, 'MM'), -1 * ROWNUM)
                                   begin_mnd,
                                LAST_DAY (
                                   ADD_MONTHS (TRUNC (SYSDATE, 'MM'), -1 * ROWNUM))
                                   eind_mnd
                           FROM DUAL
                     CONNECT BY LEVEL <= 12) periode,
                    mld_melding m,
                    mld_melding_object mo,
                    mld_stdmelding sm,
                    ins_tab_discipline vg
              WHERE     m.mld_stdmelding_key = sm.mld_stdmelding_key
                    AND sm.mld_ins_discipline_key = vg.ins_discipline_key
                    AND mld_melding_datum < periode.eind_mnd
                    AND COALESCE (mld_melding_einddatum, SYSDATE) >
                          periode.begin_mnd
                    AND m.mld_melding_key = mo.mld_melding_key) storingen
         ON objecten.periode = storingen.periode
            AND objecten.ins_deel_key = storingen.ins_deel_key
GROUP BY objecten.periode, objecten.max_dgn, objecten.locatie
ORDER BY objecten.periode, objecten.locatie;

--- Operationeel Processen 
--- Resultaat gebied 1: Top 5 vakgroep aantal meldingen per maand per locatie
CREATE OR REPLACE VIEW HCAS_V_PROCESSEN_RESG1
AS
   SELECT periode,
          locatie,
          vakgroep,
          ranking,
          aantal_mld
     FROM (SELECT periode,
                  locatie,
                  vakgroep,
                  aantal_mld,
                  RANK ()
                     OVER (PARTITION BY periode, locatie
                           ORDER BY aantal_mld DESC)
                     RANKING
             FROM (  SELECT    TO_CHAR (m.mld_melding_datum, 'YYYY')
                            || ' / '
                            || TO_CHAR (m.mld_melding_datum, 'mm')
                               AS periode,
                            l.alg_locatie_omschrijving AS locatie,
                            vg.ins_discipline_omschrijving AS vakgroep,
                            COUNT (m.mld_melding_key) AS aantal_mld
                       FROM mld_melding m,
                            mld_stdmelding sm,
                            ins_tab_discipline vg,
                            alg_locatie l
                      WHERE m.mld_stdmelding_key = sm.mld_stdmelding_key
                            AND sm.mld_ins_discipline_key =
                                  vg.ins_discipline_key
                            AND m.mld_alg_locatie_key = l.alg_locatie_key
                            AND m.mld_melding_einddatum >
                                  TO_DATE ('01-01-2000', 'dd-mm-yyyy')
                            AND MONTHS_BETWEEN (
                                  TRUNC (TRUNC (SYSDATE, 'Month'), 'Month'),
                                  m.mld_melding_datum) <
                                  12
                            AND MONTHS_BETWEEN (
                                  TRUNC (TRUNC (SYSDATE, 'Month'), 'Month'),
                                  m.mld_melding_datum) >
                                  0
                   GROUP BY    TO_CHAR (m.mld_melding_datum, 'YYYY')
                            || ' / '
                            || TO_CHAR (m.mld_melding_datum, 'mm'),
                            l.alg_locatie_omschrijving,
                            vg.ins_discipline_omschrijving
                   ORDER BY    TO_CHAR (m.mld_melding_datum, 'YYYY')
                            || ' / '
                            || TO_CHAR (m.mld_melding_datum, 'mm'),
                            l.alg_locatie_omschrijving,
                            COUNT (m.mld_melding_key) DESC)
                  meldingen_categorie) RANK
    WHERE RANKING < 6;
   
--- Operationeel Processen 
--- Resultaat gebied 2: Gem. doorlooptijd per maand, per locatie per vakgroep
CREATE OR REPLACE VIEW HCAS_V_PROCESSEN_RESG2
AS
     SELECT    TO_CHAR (m.mld_melding_einddatum, 'YYYY')
            || ' / '
            || TO_CHAR (m.mld_melding_datum, 'mm')
               AS periode,
            l.alg_locatie_omschrijving,
            vg.ins_discipline_omschrijving,
            (SUM (m.mld_melding_einddatum - m.mld_melding_datum))
            / (COUNT (m.mld_melding_key))
               AS gem_doorlooptijd
       FROM mld_melding m,
            mld_stdmelding sm,
            ins_tab_discipline vg,
            alg_locatie l
      WHERE     m.mld_stdmelding_key = sm.mld_stdmelding_key
            AND sm.mld_ins_discipline_key = vg.ins_discipline_key
            AND m.mld_alg_locatie_key = l.alg_locatie_key
            AND m.mld_melding_einddatum > TO_DATE ('01-01-2000', 'dd-mm-yyyy')
            AND MONTHS_BETWEEN (TRUNC (TRUNC (SYSDATE, 'Month'), 'Month'),
                                m.mld_melding_datum) < 12
            AND MONTHS_BETWEEN (TRUNC (TRUNC (SYSDATE, 'Month'), 'Month'),
                                m.mld_melding_datum) > 0
   GROUP BY    TO_CHAR (m.mld_melding_einddatum, 'YYYY')
            || ' / '
            || TO_CHAR (m.mld_melding_datum, 'mm'),
            l.alg_locatie_omschrijving,
            vg.ins_discipline_omschrijving
   ORDER BY    TO_CHAR (m.mld_melding_einddatum, 'YYYY')
            || ' / '
            || TO_CHAR (m.mld_melding_datum, 'mm'),
            l.alg_locatie_omschrijving,
            vg.ins_discipline_omschrijving;                                                            

--- Operationeel Processen 
--- Resultaat gebied 3: Gem. uptime van apparaten per vestiging
CREATE OR REPLACE VIEW HCAS_V_PROCESSEN_RESG3
AS
     SELECT objecten.periode,
            objecten.locatie,
            storingen.vakgroep,
            objecten.max_dgn * COUNT (objecten.ins_deel_key) max_uptime,
            COUNT (objecten.ins_deel_key) aant_obj,
            SUM (NVL (storingen.downtime, 0)) downtime,
            (objecten.max_dgn * COUNT (objecten.ins_deel_key))
            - SUM (NVL (storingen.downtime, 0))
               uptime,
            ( ( (objecten.max_dgn * COUNT (objecten.ins_deel_key))
               - SUM (NVL (storingen.downtime, 0)))
             / (objecten.max_dgn * COUNT (objecten.ins_deel_key)))
            * 100
               perc_uptime
       FROM    (SELECT    TO_CHAR (periode.begin_mnd, 'YYYY')
                       || ' / '
                       || TO_CHAR (periode.begin_mnd, 'mm')
                          AS periode,
                       eind_mnd - begin_mnd max_dgn,
                       l.alg_locatie_omschrijving locatie,
                       o.ins_deel_key
                  FROM (    SELECT ADD_MONTHS (TRUNC (SYSDATE, 'MM'), -1 * ROWNUM)
                                      begin_mnd,
                                   LAST_DAY(ADD_MONTHS (TRUNC (SYSDATE, 'MM'),
                                                        -1 * ROWNUM))
                                      eind_mnd
                              FROM DUAL
                        CONNECT BY LEVEL <= 12) periode,
                       ins_deel o,
                       alg_locatie l
                 WHERE o.ins_alg_locatie_key = l.alg_locatie_key
                       AND o.ins_deel_aanmaak < periode.begin_mnd
                       AND (o.ins_deel_verwijder > periode.eind_mnd
                            OR o.ins_deel_verwijder IS NULL)
                       AND (o.ins_deel_vervaldatum > periode.eind_mnd
                            OR o.ins_deel_vervaldatum IS NULL)) objecten
            LEFT OUTER JOIN
               (SELECT    TO_CHAR (periode.begin_mnd, 'YYYY')
                       || ' / '
                       || TO_CHAR (periode.begin_mnd, 'mm')
                          AS periode,
                       (eind_mnd - begin_mnd) max_dgn,
                       mo.ins_deel_key,
                       CASE
                          --- scenario 1: begin en eind van de melding vallen in dezelfde maand
                       WHEN (mld_melding_datum > begin_mnd
                             AND mld_melding_einddatum < eind_mnd)
                          THEN
                             mld_melding_einddatum - mld_melding_datum
                          --- scenario 2: begin van de melding valt binnen de maand maar het einde niet
                       WHEN (mld_melding_datum >= begin_mnd
                             AND mld_melding_einddatum > eind_mnd)
                          THEN
                             eind_mnd - mld_melding_datum
                          --- scenario 3: begin en einde van de melding vallen buiten de maand, dan is de downtime gewoon de max
                       WHEN (mld_melding_datum < begin_mnd
                             AND mld_melding_einddatum > eind_mnd)
                          THEN
                             eind_mnd - begin_mnd
                          --- scenario 4: meldingdatum ligt voor het begin van de maand maar de einddatum valt wel in de maand
                       ELSE
                             mld_melding_einddatum - begin_mnd
                       END
                          AS downtime,
                       m.mld_melding_key,
                       mld_melding_datum,
                       mld_melding_einddatum,
                       vg.ins_discipline_omschrijving vakgroep
                  FROM (    SELECT ADD_MONTHS (TRUNC (SYSDATE, 'MM'), -1 * ROWNUM)
                                      begin_mnd,
                                   LAST_DAY(ADD_MONTHS (TRUNC (SYSDATE, 'MM'),
                                                        -1 * ROWNUM))
                                      eind_mnd
                              FROM DUAL
                        CONNECT BY LEVEL <= 12) periode,
                       mld_melding m,
                       mld_melding_object mo,
                       mld_stdmelding sm,
                       ins_tab_discipline vg
                 WHERE     m.mld_stdmelding_key = sm.mld_stdmelding_key
                       AND sm.mld_ins_discipline_key = vg.ins_discipline_key
                       AND mld_melding_datum < periode.eind_mnd
                       AND COALESCE (mld_melding_einddatum, SYSDATE) >
                             periode.begin_mnd
                       AND m.mld_melding_key = mo.mld_melding_key) storingen
            ON objecten.periode = storingen.periode
               AND objecten.ins_deel_key = storingen.ins_deel_key
      WHERE storingen.vakgroep IS NOT NULL --- dus hier wordt alleen gekeken naar objecten die ook daadwerkelijk in storing hebben gestaan
   GROUP BY objecten.periode,
            objecten.max_dgn,
            objecten.locatie,
            storingen.vakgroep
   ORDER BY objecten.periode, objecten.locatie, storingen.vakgroep;
                 
------ payload end   ------

SET DEFINE OFF

BEGIN
   adm.systrackscriptId ('$Id$',
                         0);
END;
/

COMMIT;
SET ECHO OFF
SPOOL OFF
SET DEFINE ON
PROMPT Logfile of this upgrade is: &fcltlogfile