CREATE OR REPLACE PROCEDURE DWH."CALCOLO_SLA_TC" (dataRif IN DATE)
AS
  mese_in    NUMBER;
  anno_in    NUMBER;
  data_in     DATE;
  data_iniziale   DATE;
  cod_errore      NUMBER;
  mesecomp varchar2(7);
BEGIN
  cod_errore := 0;
  data_in := add_months(dataRif,-1);
  mese_in := to_number(to_char(data_in,'MM'),'99');
  anno_in := to_number(to_char(data_in,'YYYY'),'9999');
  mesecomp := to_char(data_in,'MM/YYYY');
  DBMS_OUTPUT.put_line('Mese da calcolare : ' || mese_in);
  DBMS_OUTPUT.put_line('Anno da calcolare : ' || anno_in);

  --------------------------------------------------------------------
  --- FACCIO UNA DELETE PREVENTIVA DELLA TABELLA PER IL MESE INTERESSATO DAL CALCOLO
  --------------------------------------------------------------------
  DELETE dwh.mnp_dw_sla_tc_out WHERE to_char(data_messaggio,'YYYYMM')=to_char(data_in,'YYYY')||to_char(data_in,'MM');
  COMMIT;

  DBMS_OUTPUT.put_line('primo step -1');
  data_iniziale := to_date('1-'|| mese_in||'-'|| anno_in,'DD-MM-YYYY');

  DBMS_OUTPUT.put_line('primo step');

  -- CARICAMENTO DATI
  -- caricamento dati nella tabella temporanea MNP_DW_SLA_TC_IN
  dwh.caricamento_sla_tc(mese_in,anno_in, cod_errore);
  DBMS_OUTPUT.put_line('secondo step');

  IF cod_errore = 0
  THEN
    -- tutto a posto
    DBMS_OUTPUT.put_line ('Avvio procedura di calcolo delle penali');
  END IF;

  -- CALCOLO SLA X  (2 giorni)
  -- calcolo i giorni di ritardo per lo SLAX
  UPDATE dwh.mnp_dw_sla_tc_out SET
    numero_giorni_ritardo = TRUNC(TRUNC(t_finale) - TRUNC(fun_giorni_piu(t_iniziale,2)))
   ,data_attesa_evento_fin=fun_giorni_piu(t_iniziale,2)
  WHERE tipo_messaggio = 'SLA X'
    AND numero_giorni_ritardo IS NULL;

 
  -- CALCOLO SLA Y (5 giorni)
  -- calcolo i giorni di ritardo per lo SLAY
  UPDATE dwh.mnp_dw_sla_tc_out SET
    numero_giorni_ritardo = TRUNC(TRUNC(t_finale) - TRUNC(fun_giorni_piu(t_iniziale,5)))
    ,data_attesa_evento_fin=fun_giorni_piu(t_iniziale,5)
  WHERE tipo_messaggio = 'SLA Y'
    AND numero_giorni_ritardo IS NULL;

 
  -- CALCOLO SLA Z (5 giorni)
  -- calcolo i giorni di ritardo per lo SLAZ
  UPDATE dwh.mnp_dw_sla_tc_out SET
    numero_giorni_ritardo = TRUNC(TRUNC(t_finale) - TRUNC(fun_giorni_piu(t_iniziale,5)))
    ,data_attesa_evento_fin=fun_giorni_piu(t_iniziale,5)
  WHERE tipo_messaggio = 'SLA Z'
    AND numero_giorni_ritardo IS NULL;


-- ######################################### --
-- ## AGGIORNAMENTO FLAG_PENALE_ALTRO_AOM ## --
-- ######################################### --

  -- QUESTA UPDATE FA SI CHE TUTTI GLI EVENTI 'SLA X', 'SLA Y' E 'SLA Z' APPENA CARICATI
  -- VENGANO IMPOSTATI CON IL FLAG A N se e' PRESENTE UN RITARDO
  UPDATE DWH.MNP_DW_SLA_TC_OUT
  SET IS_PENALE_ALTRO_AOM = 'N'
  WHERE IS_PENALE_ALTRO_AOM IS NULL  AND PROCESSO <> 'V' AND MESE_COMP_FINALE = mesecomp
    AND numero_giorni_ritardo > 0;


  -- CALCOLO FLAG PENALE ALTRO AOM SLA X DONOR
  -- LA WHERE CONDITION IS_PENALE_ALTRO_AOM IS NULL FA SI CHE CONSIDERI SOLO I DATI APPENA INSERITI
  UPDATE DWH.MNP_DW_SLA_TC_OUT
  SET IS_PENALE_ALTRO_AOM = 'Y'
  WHERE TIPO_MESSAGGIO='SLA X' AND IS_PENALE_ALTRO_AOM IS NULL AND PROCESSO = 'D' AND MESE_COMP_FINALE = mesecomp
    AND TRUNC( TRUNC(T_FINALE_ALTRO_AOM) - TRUNC(FUN_GIORNI_PIU(T_INIZIALE,2))) > 0;
  
  -- CALCOLO FLAG PENALE ALTRO AOM SLA Y DONOR
  UPDATE DWH.MNP_DW_SLA_TC_OUT
  SET IS_PENALE_ALTRO_AOM = 'Y'
  WHERE TIPO_MESSAGGIO='SLA Y' AND IS_PENALE_ALTRO_AOM IS NULL AND PROCESSO = 'D' AND MESE_COMP_FINALE = mesecomp
    AND TRUNC( TRUNC(T_FINALE_ALTRO_AOM) - TRUNC(FUN_GIORNI_PIU(T_INIZIALE,5))) > 0;

  -- CALCOLO FLAG PENALE ALTRO AOM SLA Z DONOR
  UPDATE DWH.MNP_DW_SLA_TC_OUT
  SET IS_PENALE_ALTRO_AOM = 'Y'
  WHERE TIPO_MESSAGGIO='SLA Z' AND IS_PENALE_ALTRO_AOM IS NULL AND PROCESSO = 'D' AND MESE_COMP_FINALE = mesecomp
    AND TRUNC( TRUNC(T_FINALE_ALTRO_AOM) - TRUNC(FUN_GIORNI_PIU(T_INIZIALE,5))) > 0;

  -- CALCOLO FLAG PENALE ALTRO AOM SLA X RECIPIENT
  -- LA WHERE CONDITION IS_PENALE_ALTRO_AOM IS NULL FA SI CHE CONSIDERI SOLO I DATI APPENA INSERITI
  UPDATE DWH.MNP_DW_SLA_TC_OUT
  SET IS_PENALE_ALTRO_AOM = 'Y'
  WHERE TIPO_MESSAGGIO='SLA X' AND PROCESSO = 'R' AND MESE_COMP_FINALE = mesecomp
    AND TRUNC( TRUNC(T_FINALE_ALTRO_AOM) - TRUNC(FUN_GIORNI_PIU(T_INIZIALE,2))) > 0;
  
  -- CALCOLO FLAG PENALE ALTRO AOM SLA Y RECIPIENT
  UPDATE DWH.MNP_DW_SLA_TC_OUT
  SET IS_PENALE_ALTRO_AOM = 'Y'
  WHERE TIPO_MESSAGGIO='SLA Y' AND PROCESSO = 'R' AND MESE_COMP_FINALE = mesecomp
    AND TRUNC( TRUNC(T_FINALE_ALTRO_AOM) - TRUNC(FUN_GIORNI_PIU(T_INIZIALE,5))) > 0;

  -- CALCOLO FLAG PENALE ALTRO AOM SLA Z RECIPIENT
  UPDATE DWH.MNP_DW_SLA_TC_OUT
  SET IS_PENALE_ALTRO_AOM = 'Y'
  WHERE TIPO_MESSAGGIO='SLA Z' AND PROCESSO = 'R' AND MESE_COMP_FINALE = mesecomp
    AND TRUNC( TRUNC(T_FINALE_ALTRO_AOM) - TRUNC(FUN_GIORNI_PIU(T_INIZIALE,5))) > 0;

-- ######################################### --    
    
-- ######################################### --

  -- se i giorni di ritardo sono < 0 (non c'e' ritardo)
  -- cancello i record corrispondenti
  DELETE FROM dwh.mnp_dw_sla_tc_out
  WHERE numero_giorni_ritardo <= 0 
    and is_penale_altro_aom IS NULL;

  DELETE FROM dwh.mnp_dw_sla_tc_out
  WHERE numero_giorni_ritardo is null and is_penale_altro_aom IS NULL;
    

  -- INFINE CALCOLO LA PENALE DI 10 EURO AL GIORNO
  UPDATE dwh.mnp_dw_sla_tc_out
  SET penale = numero_giorni_ritardo * F_ESTRAI_IMPORTO_SLA(decode(processo,'D',donor_effettivo,'R',recipient_effettivo,
    'V',decode(donor_effettivo,'TIMG',donor_effettivo,recipient_effettivo)),TIPO_MESSAGGIO)
  WHERE numero_giorni_ritardo > 0
    AND penale IS NULL;

  COMMIT;
  DBMS_OUTPUT.put_line ('Calcolo penali completato con successo');

EXCEPTION
WHEN OTHERS THEN
  cod_errore := 1;
  DBMS_OUTPUT.put_line ('Errore in CALCOLO_SLA_TC ' || SQLERRM);
  RETURN;
END CALCOLO_SLA_TC;
/
