CREATE OR REPLACE PROCEDURE CALCOLA_SLA_DONOR ( mese_in IN NUMBER, anno_in IN NUMBER, cod_errore IN OUT NUMBER ) IS -- Purpose: Calcolo degli SLA Donor -- La procedura calcola gli SLA Donor relativi al mese di riferimento per tutte -- le richieste contenute nella tabella MNP_DW_DONOR_DELTA ed inserisce un record -- con i valori caolcolati nella tabella MNP_DW_DONOR_SLA -- MODIFICATION HISTORY -- A.Parati 15/07/2004 Versione Iniziale -- A.Parati 22/07/2004 Modifica all'algoritmo di calcolo degli SLA -- A.Parati 17/08/2004 Correzione errori di calcolo -- L.Marcucci 15/10/2004 Correzione errori di calcolo SLA1 e SLA2 ultimo_giorno_mese DATE; -- Ultimo giorno lavorativo del mese di riferiemnto primo_giorno_mese DATE; -- Primo giorno lavorativo del mese di riferimento app_id_richiesta dwh.mnp_dw_donor_delta.id_richiesta%TYPE; -- identificativo della richiesta di cui calcolare gli sla sla0_minore dwh.mnp_dw_donor_sla.sla_zero_minore%TYPE; -- numero di giorni di SLA0<=4 relativi al mese calcolato su SLA precedenti sla0_maggiore dwh.mnp_dw_donor_sla.sla_zero_maggiore%TYPE; -- numero di giorni di SLA0>4 relativi al mese calcolato su SLA precedenti sla1_minore dwh.mnp_dw_donor_sla.sla_uno_minore%TYPE; -- numero di giorni di SLA1<=4 relativi al mese sla1_maggiore dwh.mnp_dw_donor_sla.sla_uno_maggiore%TYPE; -- numero di giorni di SLA1>4 relativi al mese sla2_minore dwh.mnp_dw_donor_sla.sla_due_minore%TYPE; -- numero di giorni di SLA2<=4 relativi al mese sla2_maggiore dwh.mnp_dw_donor_sla.sla_due_maggiore%TYPE; -- numero di giorni di SLA2>4 relativi al mese sla0 NUMBER; -- numero di giorni di SLA0 totale sla1 NUMBER; -- numero di giorni di SLA1 totale sla2 NUMBER; -- numero di giorni di SLA2 totale app_stato NUMBER; -- stato attuale della richiesta app_data_presa_in_carico DATE; -- data di presa in carico app_data_ricezione_richiesta DATE; -- data ricezione richiesta app_data_validazione DATE; -- data di validazione app_data_validazione_max DATE; -- data di validazione massima app_data_espletamento DATE; -- data di espletamento app_data_stato_finale DATE; -- data in cui la richiesta ha terminato il processo app_data_cut_over_calc DATE; -- data di cut over calcolata bound NUMBER := 4; -- Limite per la separazione dei giorni/ore di ritardo sla1_mese_corrente NUMBER; -- numero di giorni di SLA1 nel mese di riferimento sla1_mesi_precedenti NUMBER; -- numero di giorni di SLA1 dei mesi precedenti sla2_mese_corrente NUMBER; -- numero di giorni di SLA2 nel mese di riferimento sla2_mesi_precedenti NUMBER; -- numero di giorni di SLA2 dei mesi precedenti var_stato_finale NUMBER; -- variabile di appoggio per il codice dello sto finale file_log UTL_FILE.file_type; -- file di log dir_out_log VARCHAR2 (200); line_log VARCHAR2 (200); -- Cursore per le richieste di cui calcolare gli SLA CURSOR cur_richiesta IS SELECT id_richiesta, stato, data_presa_in_carico, data_ricezione_richiesta, data_validazione, data_validazione_max, data_espletamento, data_stato_finale, data_cut_over_calc FROM dwh.mnp_dw_donor_delta; BEGIN cod_errore := 0; dir_out_log := 'SLA'; file_log := UTL_FILE.fopen ( dir_out_log, 'SLA_DONOR_' || TO_CHAR (SYSDATE, 'yyyyMMdd') || '.log', 'w' ); UTL_FILE.put_line ( file_log, TO_CHAR (SYSDATE, 'yyyyMMdd HH24:mi:ss') || ': INIZIO CALCOLO SLA DONOR' ); UTL_FILE.fflush (file_log); DELETE FROM dwh.mnp_dw_donor_sla WHERE mese = mese_in AND anno = anno_in; COMMIT; -- Calcolo ultimo giorno lavorativo del mese ultimo_giorno_mese := dwh.fun_ultimo_giorno_lavorativo (mese_in, anno_in); -- Calcolo primo giorno lavorativo del mese primo_giorno_mese := dwh.fun_primo_giorno_lavorativo (mese_in, anno_in); OPEN cur_richiesta; -- Per ogni richiesta di cui devo calcolare gli SLA LOOP FETCH cur_richiesta INTO app_id_richiesta, app_stato, app_data_presa_in_carico, app_data_ricezione_richiesta, app_data_validazione, app_data_validazione_max, app_data_espletamento, app_data_stato_finale, app_data_cut_over_calc; EXIT WHEN cur_richiesta%NOTFOUND; -- Inizializzazione variabili sla0_minore := 0; sla0_maggiore := 0; sla1_minore := 0; sla1_maggiore := 0; sla2_minore := 0; sla2_maggiore := 0; sla0 := 0; sla1 := 0; sla2 := 0; sla1_mese_corrente := 0; sla1_mesi_precedenti := 0; sla2_mese_corrente := 0; sla2_mesi_precedenti := 0; -- Calcolo SLA0 totale -- se la data di presa in carico h nulla lo sla non viene calcolato IF app_data_presa_in_carico IS NULL THEN sla0 := 0; ELSE IF (TRUNC (app_data_presa_in_carico) <= ultimo_giorno_mese) AND (TRUNC (app_data_presa_in_carico) >= primo_giorno_mese) THEN sla0 := dwh.fun_giorni_lavorativi ( app_data_presa_in_carico, app_data_ricezione_richiesta ) - 1; ELSE sla0 := 0; END IF; END IF; BEGIN SELECT DECODE (finale, 1, id_stato, 0, -1) INTO var_stato_finale FROM mnp.mnp_stato WHERE id_stato = app_stato; EXCEPTION WHEN NO_DATA_FOUND THEN var_stato_finale := -1; END; -- Calcolo SLA1 totale IF (TRUNC (app_data_validazione_max) <= ultimo_giorno_mese) AND ( app_data_validazione IS NULL OR app_data_validazione >= primo_giorno_mese ) THEN IF app_data_validazione IS NULL THEN IF app_stato = var_stato_finale THEN app_data_validazione := app_data_stato_finale; ELSE app_data_validazione := FUN_GIORNI_PIU(ultimo_giorno_mese,1); END IF; END IF; sla1 := dwh.fun_giorni_lavorativi ( app_data_validazione, app_data_validazione_max ); IF sla1 > 0 THEN IF TRUNC (app_data_validazione_max) >= primo_giorno_mese THEN sla1_mese_corrente := sla1; ELSE sla1_mese_corrente := dwh.fun_giorni_lavorativi ( app_data_validazione, primo_giorno_mese ); END IF; ELSE sla1 := 0; sla1_mese_corrente := 0; END IF; ELSE sla1 := 0; sla1_mese_corrente := 0; END IF; -- Calcolo SLA1 mesi precedenti sla1_mesi_precedenti := sla1 - sla1_mese_corrente; -- Verifico se gli SLA sono positivi IF sla1 < 0 THEN sla1 := 0; END IF; IF sla1_mese_corrente < 0 THEN sla1_mese_corrente := 0; END IF; IF sla1_mesi_precedenti < 0 THEN sla1_mesi_precedenti := 0; END IF; -- Calcolo SLA2 totale IF (TRUNC (app_data_cut_over_calc) <= ultimo_giorno_mese) AND ( app_data_espletamento IS NULL OR app_data_espletamento >= primo_giorno_mese ) THEN IF app_data_espletamento IS NULL THEN IF app_stato = var_stato_finale THEN app_data_espletamento := app_data_stato_finale; ELSE app_data_espletamento := FUN_GIORNI_PIU(ultimo_giorno_mese,1); END IF; END IF; sla2 := dwh.fun_giorni_lavorativi ( app_data_espletamento, app_data_cut_over_calc ); IF sla2 > 0 THEN IF TRUNC (app_data_cut_over_calc) >= primo_giorno_mese THEN sla2_mese_corrente := sla2; ELSE sla2_mese_corrente := dwh.fun_giorni_lavorativi ( app_data_espletamento, primo_giorno_mese ); END IF; ELSE sla2 := 0; sla2_mese_corrente := 0; END IF; ELSE sla2 := 0; sla2_mese_corrente := 0; END IF; -- Calcolo SLA2 mesi precedenti sla2_mesi_precedenti := sla2 - sla2_mese_corrente; -- Verifico se gli SLA sono positivi IF sla2 < 0 THEN sla2 := 0; END IF; IF sla2_mese_corrente < 0 THEN sla2_mese_corrente := 0; END IF; IF sla2_mesi_precedenti < 0 THEN sla2_mesi_precedenti := 0; END IF; -- Calcolo SLA0 relativo al mese di riferimento IF sla0 > 0 THEN IF sla0 <= bound THEN sla0_minore := sla0; sla0_maggiore := 0; ELSE sla0_minore := bound; sla0_maggiore := sla0 - bound; END IF; ELSE -- se lo SLA totale h <= 0 gli SLA relativi al mese sono 0 sla0_minore := 0; sla0_maggiore := 0; END IF; -- ************************ CALCOLO SLA1 SULLE DATE **************************** IF sla1_mese_corrente = 0 THEN -- lo SLA1 del mese corrente h 0 sla1_minore := 0; sla1_maggiore := 0; ELSE -- lo SLA1 del mese corrente h positivo IF sla1_mesi_precedenti >= bound THEN sla1_minore := 0; sla1_maggiore := sla1_mese_corrente; ELSE IF sla1_mese_corrente >= bound - sla1_mesi_precedenti THEN sla1_minore := bound - sla1_mesi_precedenti; sla1_maggiore := sla1 - bound; ELSE -- lo SLA1 del mese corrente h minore di 4 - SLA1 dei mesi precedenti sla1_minore := sla1_mese_corrente; sla1_maggiore := 0; END IF; END IF; END IF; -- ************************ FINE CALCOLO SLA1 SULLE DATE **************************** -- ************************ CALCOLO SLA2 SULLE DATE **************************** IF sla2_mese_corrente = 0 THEN -- lo SLA2 del mese corrente h 0 sla2_minore := 0; sla2_maggiore := 0; ELSE -- lo SLA2 del mese corrente h positivo IF sla2_mesi_precedenti >= bound THEN sla2_minore := 0; sla2_maggiore := sla2_mese_corrente; ELSE IF sla2_mese_corrente >= bound - sla2_mesi_precedenti THEN sla2_minore := bound - sla2_mesi_precedenti; sla2_maggiore := sla2 - bound; ELSE -- lo SLA2 del mese corrente h minore di 4 - SLA2 dei mesi precedenti sla2_minore := sla2_mese_corrente; sla2_maggiore := 0; END IF; END IF; END IF; -- ************************ FINE CALCOLO SLA2 SULLE DATE **************************** -- Se esiste almeno uno SLA nel mese di riferimento IF sla0_minore > 0 OR sla0_maggiore > 0 OR sla1_minore > 0 OR sla1_maggiore > 0 OR sla2_minore > 0 OR sla2_maggiore > 0 THEN -- Inserimento del record relativo al mese nella tabella degli SLA INSERT INTO dwh.mnp_dw_donor_sla (id_richiesta, mese, anno, sla_zero_minore, sla_zero_maggiore, sla_uno_minore, sla_uno_maggiore, sla_due_minore, sla_due_maggiore) VALUES (app_id_richiesta, mese_in, anno_in, sla0_minore, sla0_maggiore, sla1_minore, sla1_maggiore, sla2_minore, sla2_maggiore); COMMIT; END IF; END LOOP; CLOSE cur_richiesta; DELETE FROM dwh.mnp_dw_donor d WHERE NOT EXISTS ( SELECT id_richiesta FROM dwh.mnp_dw_donor_sla ds WHERE ds.id_richiesta = d.id_richiesta); COMMIT; UTL_FILE.put_line ( file_log, TO_CHAR (SYSDATE, 'yyyyMMdd HH24:mi:ss') || ': FINE CALCOLO SLA DONOR' ); UTL_FILE.fflush (file_log); UTL_FILE.fclose (file_log); EXCEPTION WHEN OTHERS THEN cod_errore := 1; DBMS_OUTPUT.put_line ( 'Errore in CALCOLA_SLA_DONOR ' || SQLERRM); RETURN; END; -- Procedure /