Cerca nel blog

venerdì 18 settembre 2015

ABAP - BADI (Business Add-Ins)

Definizione di BADI

Le Badi (Business ADD-INS) sono classi OO dove è possibile aggiungere codice personalizzato, in metodi appropriati, che sono chiamati da codice standard. La caratteristica principale di una BAdI è che fornisce un meccanismo per modificare la funzionalità di una funzione aziendale ben definita (ad esempio un BAPI) senza apportare modifiche al codice sorgente.

Creazione di una BADI Custom

Supponiamo di voler calcolare l'IVA di diversi movimenti contabili. Le voci devono essere passate a un metodo che calcola e restituisce l'IVA. Dato che a priori, non possiamo sapere quale sia l'IVA di un determinato paese, definiamo una BADI con il metodo get_vat. Questo metodo deve restituire l'IVA per un particolare valore che viene passato al metodo get_vat. I passi da seguire sono i seguenti
  • CREAZIONE DI UN ENHANCEMENT SPOT: la prima cosa da fare quando si crea un Badi, è quella di creare un contenitore per la Badi. Questo significa creare un semplice Enhancement Spot, dove svilupperemo la nostra Badi. Richiamare la transazione SE18 ed inserire il nome dell’Enhancement che vogliamo creare, e premere il pulsante CREARE.

Nella pop-up successiva , inserire una descrizione dell’Enhancement e premere invio:  


  • CREAZIONE DELLA BADI: per creare la badi con il nuovo enhancement spot, premere il pulsante Creare Badi come mostrato in figura:

 
  • Nella pop-up successiva, inserire il nome della BADI , in questo caso z_badi_calc_vat, ed una breve descrizione.

  • Nella schermata successiva, deselezionare l'opzione “Util. Multiplo”.

 
  • CREAZIONE INTERFACCIA: dopo aver creato la Badi, è necessario creare un’interfaccia nel quale definiamo i metodi che determinano cosa fa la nostra Badi. Fare doppio click sull’Icona Interface, inserire il nome dell’interfaccia e premere il pulsante con la matita.



  • Inseriamo il nome del metodo che vogliamo creare nella nostra badi, in questo caso, inseriremo “GET_VAT” ed i parametri necessari.
  • Premiamo sul pulsante “Parametri” per inserire i parametri del metodo.
  •  Salvare e attivare l’interfaccia e l’enhancement.
  • Tuttavia, solo la costruzione di una BAdI non è sufficiente in quanto non fa nulla. E’ necessario un’istanza della BAdI e questa instanza deve essere chiamata in qualche parte del codice. Dal momento che la BAdI definisce solo l'interfaccia, è necessaria una classe che implementa questa interfaccia.
  • SCRIVERE DEL CODICE SORGENTE: Ora è necessario scrivere del codice ABAP per usare la BAdI. Abbiamo bisogno di una variabile che fa riferimento alla BAdI e alcune variabili che vengono passate come parametri attuali al metodo BAdI. Successivamente, è necessario creare handle per la BAdI e chiamare il metodo get_vat della BAdI. I rispettivi comandi sono GET BADI e CALL BADI.
  • Creare il programma ZCALC_VAT, con il seguente codice:
              REPORT zcalc_vat.    

      
DATAhandle  TYPE REF TO z_badi_calc_vat,
              
sum     TYPE p,
               vat     
TYPE p,
               percent 
TYPE p.

      
START-OF-SELECTION.

      
sum 50.

      
GET BADI handle.

      
CALL BADI handle->get_vat
          
EXPORTING
             im_amount      
sum
          
IMPORTING
             ex_amount_vat  
vat
             ex_percent_vat 
percent.


       write: / 'percentage:', percent,  ' VAT: ', vat.

NOTA: Se si esegue il programma in questa fase, va in Dump. Questo perché è obbligatorio avere esattamente una implementazione attiva per il single-use BAdI. È possibile gestire questo errore catturandolo con l’eccezione cx_badi_not_implemented. In altre parole si dovrebbe modificare il programma in questo modo:

       TRY.

      
GET BADI handle.

      
CALL BADI handle->get_vat
        
EXPORTING
          im_amount      
sum
        
IMPORTING
          ex_amount_vat  
vat
          ex_percent_vat 
percent.

    CATCH cx_badi_not_implemented cx_badi_initial_reference.
  
ENDTRY.

        write: / 'percentage:', percent,  ' VAT: ', vat.

NOTA: La soluzione migliore è quella di utilizzare una FALLBACK CLASS (classe di ripiego). Questa classe viene utilizzata se non ci sono implementazioni di BAdI attive.
Il comando GET BADI restituisce un handle a un'istanza della classe fallback e la rispettiva CALL BADI chiama i metodi della istanza di classe fallback. Non appena vi è una implementazione BADI attiva, la classe fallback non è più utilizzato in fase di esecuzione.
CON L’USO DEL FALLBACK CLASS, IL PROGRAMMA CHE RICHIAMA LA BADI NON NECESSITA DI GESTIRE L’ECCEZIONE COME FATTO IN PRECEDENZA.
  
CREAZIONE FALLBACK CLASS: per la creazione di tale class, procedere ne seguente modo:
Selezionare l’opzione “Call fallback class if no implementation is executed” ed inserire il nome della class, ad esempio Z_CL_CALC_VAT_FB e premere il pulsante della Matita.


Il relativo metodo dell’interfaccia Badi è già definito automaticamente. Dobbiamo solo implementarla, quindi inseriamo il seguente codice, successivamente SALVARE ed ATTIVARE.

  METHOD z_if_calc_vat~get_vat.

    
DATApercent TYPE VALUE 20.

    ex_amount_vat 
im_amount * percent / 100.

    ex_percent_vat 
percent.

  
ENDMETHOD.

Navigare nell’Enhancement Spot e Attivarlo. Modificare il programma creato in precedenza commentando il Try… Catch, ed eseguirlo, in questo caso non va in Dump, ma stampa il seguente valore:

percentage: 20 VAT: 10.

Implementare una BADI Custom

La classe FALLBACK viene creata solo in caso non sia disponibile nessuna implementazione dela BADi. Non appena vi è una implementazione adeguata della BAdI, i metodi della classe fallback non vengono più utilizzati.
  • CREAZIONE DI UN ENHANCEMENT IMPLEMENTATION: non si può implementare una Badi se non si crea prima un contenitore. Per fare ciò, richiamare la transazione SE18, ed inserire l’Enhancement Spot creato in precedenza, Z_ES_CALCULATE_TAX e premere il pulsante Modificare. Nella schermata successiva selezionare la Badi Z_BADI_CALC_VAT e premere il pulsante Create Enhancement Implementation

  • Nella pop-up successiva, inserire il nome e la descrizione dell’Enhancement Implementation.

  • Nella pop-up successiva, inserire il nome della Badi Definition creata in precedenza Z_BADI_CALC_VAT ed il nome della Badi Implementation che vogliamo creare Z_BDI_CALC_VAT_US ed la classe implementation.

Premere Ok, e verrà visualizzata la seguente schermata, in cui viene riepilogata la classe che stiamo creando, a questo punto premiamo il pulsante "Classe Vuota".


  • IMPLEMENTARE LA CLASSE: Ora che abbiamo implementato la BADI, dobbiamo implementare la relativa classe: Espandere il relativo “albero” nel nome della Badi “Z_BDI_CALC_VAT_US”. Fare doppio click su “Implementing Class”, inserire il nome della classe e premere il pulsante di modifica.


  •  Si apre il Class Builder. I metodi di interfaccia sono già definiti. Nel nostro caso c’è solo il metodo GET_VAT(). Nel metodo inseriamo il seguente codice:
    DATApercent TYPE VALUE 20.

    ex_amount_vat 
im_amount * percent / 100.

    
ex_percent_vat percent.

  • SALVARE e ATTIVARE la classe. Eseguendo il programma creato in precedenza per richiamare la badi, come si può vedere non richiama la FALLBACK CLASS, perché in questo caso la badi ha un’implementazione attiva.
  • CREAZIONE DI UN SECONDA BADI IMPLEMENTATION: Creiamo un'altra implementazione BADI, questa volta con l'aliquota IVA della Gran Bretagna. Per fare ciò, richiamare la transazione SE18, ed inserire l’Enhancement Spot creato in precedenza, Z_ES_CALCULATE_TAX e premere il pulsante Modificare. Nella schermata successiva selezionare la Badi Z_BADI_CALC_VAT e premere il pulsante Create Enhancement Implementation
  • Nella pop-up successiva, inserire il nome della seconda badi e la descrizione dell’Enhancement Implementation.
  • Nella pop-up successiva, inserire il nome della Badi Definition creata in precedenza Z_BADI_CALC_VAT ed il nome della Badi Implementation che vogliamo creare Z_BDI_CALC_VAT_GB ed la classe implementation Z_CL_CALC_VAT_GB.

 
  • Premere Ok, e verrà visualizzata la seguente schermata, in cui viene riepilogata la classe che stiamo creando, a questo punto premiamo il pulsante "Classe Vuota".

  • IMPLEMENTARE LA CLASSE: Ora che abbiamo implementato la BADI, dobbiamo implementare la relativa classe: Espandere il relativo “albero” nel nome della Badi “Z_BDI_CALC_VAT_GB”. Fare doppio click su “Implementing Class”, selezionare la classe e premere il pulsante di modifica.
  • Si apre il Class Builder. L'implementazione del metodo get_vat è lo stesso che per gli Stati Uniti, tranne per il tasso dell'IVA, che si assume essere 18%.
  • Nel metodo inseriamo il seguente codice:

    DATApercent TYPE VALUE 18.

    ex_amount_vat 
im_amount * percent / 100.

    
ex_percent_vat percent.
  • SALVARE e ATTIVARE la classe. Adesso se proviamo ad eseguire il programma creato in precedenza, andrà in Dump perché si verifica l’eccezione CX_BADI_MULTIPLY_IMPLEMENTED.

NOTA: Il dump è dovuto al fatto che abbiamo creato la Badi Deselezionando l’opzione di “Utilizzo Multiplo”. Quando una Badi è di tipo “Monouso”, è necessario verificare che ci sia una SOLA implementazione attiva, e non come in questo caso 2 , uno per l’US e l’altra per GB. Per risolvere il problema, E’ NECESSARIO CREARE UN FILTRO, in modo tale da scegliere la diversa implementazione della BADI.

Creazione Filtri

Per la creazione del filtro, è necessario modificare la definizione della Badi. E’ possibile definire una o più filtri per una Badi. Ai fini di questo esempio, creiamo un solo filtro. Nella definizione della Badi, bisogna definire i valori del filtro per le rispettive implementazioni delle BADI, ed utilizzare il filtro nella creazione delle istanze del Badi Handle .
Richiamare la transazione SE18, ed inserire l’Enhancement Spot creato in precedenza Z_ES_CALCULATE_TAX. Selezionare il flag "Utilizzo Filtro LIMITATO", salvare e attivare anche in caso di errori.



Successivamente selezionare il tab Enh. Spot Element Definition. Mettersi in modalita Modifica, selezionare la BADI presente nella lista, tasto destro e selezionare Creare Filtro.



Nella schermata successiva, inserire il “Badi: filtro”, “Filter Type” e la descrizione.


Premere ok. Il filtro è ora visibile come una proprietà sotto il BAdI.

Fare doppio click su Implementation, e passare nel riquadro a destra dove sono presenti tutte le implementazioni delle Badi. Per ogni implementazione, premere il pulsante “Valori Filtro”  per settare il filtro. In questo esempio: selezioniamo prima l’implementazione Z_BDI_CALS_GB, e premiamo il pulsante“Valori Filtro”,  e successivamente facciamo doppio click sulla badi Z_BDI_CALC_VAT_GB. Potrebbe comparire questo messaggio di Warning, procedere clicclando sul tab "Elementi di implementazione d'ampl"


Nel riquadro di sinistra, dove è presente l’implementazione Z_BDI_CALC_VAT_GB, facciamo doppio click su Filter e nel riquadro di destra premere il pulsante Create Filter Combination.


Fare doppio click sul filtro COUNTRY, ed inserire il valore GB e l’operatore di Uguaglianza.



Salvare ed attivare.
Facciamo la stessa operazione anche per l’implementazione Z_BDI_CALS_US,e come valore di filtro inseriamo US.
Adesso, dobbiamo modificare il programma ZCALC_VAT creato in precedenza per aggiungere il parametro filtro nel comando GET  BADI
REPORT zcalc_vat.

parametersctry(2type c.

DATAhandle  TYPE REF TO z_badi_calc_vat,
      
sum     TYPE p,
      vat     
TYPE p,
      percent 
TYPE p.

START-OF-SELECTION.

  
sum 50.

      
GET BADI handle FILTERS Country ctry.

      
CALL BADI handle->get_vat
        
EXPORTING
          im_amount      
sum
        
IMPORTING
          ex_amount_vat  
vat
          ex_percent_vat 
percent.


  
WRITE'percentage:'percent'VAT:'vat.

Visualizzazioni Ampliamenti di una BAdi


Per visualizzare gli ampliamenti in una BADI, richiamare la transazione SE18, inserire  il nome della BADI, e dal menu selezionare Implementation -> Overview

Ricercare BAdi

Una badi è possibile ricercarla nei seguenti modi:
  • Ricercare BADI tramite FM:
    Usare la transazione SE37: SXV_GET_CLIF_BY_NAME
    Mettere breakpoint sulla call function “SXV_ADD_PREFIX”
    Lanciare la transazione per vedere il nome della  BADI

    • Ricercare BADI tramite Class:
    Usare la transazione SE24: CL_EXITHANDLER Metodo: GET_INSTANCE
    Mettere breakpoint sul CALL METHOD cl_exithandler=>get_class_name_by_interface
    Lanciare la transazione per vedere il nome della  BADI
    Controllare il parametro EXIT_NAME

    • Ricercare BADI durante il Debug:
    Per cercare le badi durante il Debug, selezionare dal menu Breakpoints - > Create Breakpoints -> tab ABAP Cmnds -> scrivere “get badi” e premere invio