BAdIs y Enhancements en ABAP: GET BADI, CALL BADI

Kategorie
ABAP-Statements
Veröffentlicht
Autor
Johannes

Los BAdIs (Business Add-Ins) son el mecanismo de ampliacion moderno en SAP. Permiten modificar el comportamiento estandar de SAP sin cambiar el codigo original. Con Enhancement Spots se pueden definir puntos de ampliacion propios.

Tipos de BAdI

TipoDescripcion
BAdI clasicoSE18/SE19, obsoleto
BAdI nuevoEnhancement Spot, GET/CALL BADI
BAdI con filtroImplementacion dependiente del contexto
BAdI FallbackImplementacion por defecto

Sintaxis del nuevo BAdI

" Obtener handle del BAdI
GET BADI lo_badi.
" Llamar BAdI
CALL BADI lo_badi->method_name
EXPORTING param = value
IMPORTING result = lv_result.

Ejemplos

1. Implementar BAdI (nuevo BAdI)

" 1. Encontrar Enhancement Spot (SE18)
" Ejemplo: BADI_SD_SALES
" 2. Crear implementacion (SE19)
" Enhancement Implementation: ZEI_SD_SALES
" BAdI Implementation: ZBI_SD_SALES
" 3. Clase de implementacion
CLASS zcl_sd_sales_badi DEFINITION
PUBLIC FINAL
CREATE PUBLIC.
PUBLIC SECTION.
INTERFACES: if_badi_sd_sales.
ENDCLASS.
CLASS zcl_sd_sales_badi IMPLEMENTATION.
METHOD if_badi_sd_sales~check_document.
" Verificacion especifica del cliente
IF is_header-auart = 'ZOR'.
" Tratamiento especial para tipo de pedido ZOR
IF is_header-vkorg NOT IN gt_allowed_orgs.
ev_error = abap_true.
ev_message = 'Tipo de pedido ZOR no permitido para esta org. ventas'.
ENDIF.
ENDIF.
ENDMETHOD.
METHOD if_badi_sd_sales~modify_data.
" Modificar datos antes de guardar
IF cs_header-bstkd IS INITIAL.
cs_header-bstkd = |AUTO-{ sy-datum }|.
ENDIF.
ENDMETHOD.
ENDCLASS.

2. Llamar BAdI en codigo propio

" Encontrar definicion del BAdI
DATA: lo_badi TYPE REF TO badi_sd_sales.
" Obtener handle
GET BADI lo_badi.
" Llamar metodo
CALL BADI lo_badi->check_document
EXPORTING
is_header = ls_header
IMPORTING
ev_error = lv_error
ev_message = lv_message.
IF lv_error = abap_true.
MESSAGE lv_message TYPE 'E'.
ENDIF.

3. Crear BAdI propio

" 1. Crear Enhancement Spot (SE18)
" Nombre: ZES_ORDER_PROCESSING
" Descripcion breve: Order Processing Extensions
" 2. Crear definicion del BAdI
" Nombre: ZBADI_ORDER_CHECK
" Interfaz: ZIF_ORDER_CHECK
" 3. Definir interfaz
INTERFACE zif_order_check PUBLIC.
METHODS: validate_order
IMPORTING
is_order TYPE ty_order
EXPORTING
ev_valid TYPE abap_bool
et_messages TYPE bapiret2_t.
METHODS: enrich_order
CHANGING
cs_order TYPE ty_order.
ENDINTERFACE.
" 4. Usar en codigo propio
CLASS zcl_order_processor DEFINITION.
PUBLIC SECTION.
METHODS: process_order
IMPORTING is_order TYPE ty_order
RAISING zcx_order_error.
ENDCLASS.
CLASS zcl_order_processor IMPLEMENTATION.
METHOD process_order.
DATA: lo_badi TYPE REF TO zbadi_order_check,
lv_valid TYPE abap_bool,
lt_messages TYPE bapiret2_t.
" Obtener y llamar BAdI
GET BADI lo_badi.
CALL BADI lo_badi->validate_order
EXPORTING is_order = is_order
IMPORTING ev_valid = lv_valid
et_messages = lt_messages.
IF lv_valid = abap_false.
RAISE EXCEPTION TYPE zcx_order_error
EXPORTING messages = lt_messages.
ENDIF.
" Enriquecer datos
DATA(ls_order) = is_order.
CALL BADI lo_badi->enrich_order
CHANGING cs_order = ls_order.
" Procesamiento adicional...
ENDMETHOD.
ENDCLASS.

4. BAdI con filtro

" Definicion del BAdI con filtro (SE18):
" Filtro: VKORG (Organizacion de ventas)
" Implementacion para org. ventas 1000
CLASS zcl_badi_vkorg_1000 DEFINITION.
PUBLIC SECTION.
INTERFACES: zif_sales_badi.
ENDCLASS.
CLASS zcl_badi_vkorg_1000 IMPLEMENTATION.
METHOD zif_sales_badi~process.
" Logica solo para org. ventas 1000
cs_data-discount = '10.00'.
ENDMETHOD.
ENDCLASS.
" Implementacion para org. ventas 2000
CLASS zcl_badi_vkorg_2000 DEFINITION.
PUBLIC SECTION.
INTERFACES: zif_sales_badi.
ENDCLASS.
CLASS zcl_badi_vkorg_2000 IMPLEMENTATION.
METHOD zif_sales_badi~process.
" Otra logica para org. ventas 2000
cs_data-discount = '15.00'.
ENDMETHOD.
ENDCLASS.
" Llamada con filtro
DATA: lo_badi TYPE REF TO zbadi_sales.
GET BADI lo_badi
FILTERS
vkorg = lv_vkorg. " Solo implementacion correspondiente
CALL BADI lo_badi->process
CHANGING cs_data = ls_data.

5. Clase Fallback (implementacion por defecto)

" BAdI con Fallback (SE18):
" Clase Fallback: ZCL_DEFAULT_HANDLER
CLASS zcl_default_handler DEFINITION
PUBLIC FINAL.
PUBLIC SECTION.
INTERFACES: zif_custom_badi.
ENDCLASS.
CLASS zcl_default_handler IMPLEMENTATION.
METHOD zif_custom_badi~process.
" Comportamiento estandar si no hay implementacion activa
rv_result = 'DEFAULT'.
ENDMETHOD.
ENDCLASS.
" Llamada - Fallback se usa si no hay impl. activa
DATA: lo_badi TYPE REF TO zbadi_custom.
GET BADI lo_badi.
" Verificar si existe implementacion
IF lo_badi IS BOUND.
CALL BADI lo_badi->process
IMPORTING rv_result = lv_result.
ENDIF.

6. Multiples implementaciones

" BAdI permite multiples implementaciones (Multiple Use)
" Se llaman todas las implementaciones activas
DATA: lo_badi TYPE REF TO zbadi_validators,
lt_messages TYPE bapiret2_t.
GET BADI lo_badi.
" Se recorren todas las implementaciones
CALL BADI lo_badi->validate
EXPORTING is_data = ls_data
CHANGING ct_messages = lt_messages.
" lt_messages contiene mensajes de todas las implementaciones
IF line_exists( lt_messages[ type = 'E' ] ).
" Al menos una implementacion reporto errores
ENDIF.

7. Enhancement Implementations

" Enhancement Points implicitos en codigo estandar
" Pueden ampliarse sin modificacion
" En codigo estandar existe:
" ENHANCEMENT-POINT ep_before_save SPOTS es_order.
" Implementacion propia (SE19):
ENHANCEMENT zei_order_enhancement.
" Codigo se inserta en este punto
IF ls_order-custom_field IS INITIAL.
ls_order-custom_field = 'DEFAULT'.
ENDIF.
ENDENHANCEMENT.

8. Enhancement Sections

" En codigo estandar:
" ENHANCEMENT-SECTION es_validation SPOTS es_order.
" " Codigo original
" IF lv_amount < 0.
" lv_error = abap_true.
" ENDIF.
" END-ENHANCEMENT-SECTION.
" Implementacion propia reemplaza original:
ENHANCEMENT zei_validation_replacement.
" Codigo propio reemplaza original
IF lv_amount < 0 OR lv_amount > 1000000.
lv_error = abap_true.
ENDIF.
ENDENHANCEMENT.

9. BAdI en RAP

" Extension Include en RAP Behavior Definition:
" managed implementation in class zbp_i_order unique;
" with additional save
" {
" ...
" determination SetDefaults on save { create; }
" }
" BAdI para extensiones RAP
INTERFACE zif_rap_order_extension PUBLIC.
METHODS: on_before_save
CHANGING ct_orders TYPE zt_orders.
METHODS: on_after_save
IMPORTING it_orders TYPE zt_orders.
ENDINTERFACE.
" Llamar en Behavior Handler
CLASS lhc_order DEFINITION INHERITING FROM cl_abap_behavior_handler.
PRIVATE SECTION.
METHODS save_modified FOR SAVE
IMPORTING it_orders FOR CREATE order.
ENDCLASS.
CLASS lhc_order IMPLEMENTATION.
METHOD save_modified.
DATA: lo_badi TYPE REF TO zbadi_rap_order.
" BAdI antes de guardar
GET BADI lo_badi.
DATA(lt_orders) = CORRESPONDING zt_orders( it_orders ).
CALL BADI lo_badi->on_before_save
CHANGING ct_orders = lt_orders.
" Guardar...
" BAdI despues de guardar
CALL BADI lo_badi->on_after_save
EXPORTING it_orders = lt_orders.
ENDMETHOD.
ENDCLASS.

10. BAdI clasico (Legacy)

" BAdI clasico de SE18 (antes de Enhancement Spots)
DATA: lo_badi TYPE REF TO if_ex_badi_name.
" Obtener handle
CALL METHOD cl_exithandler=>get_instance
CHANGING instance = lo_badi.
" Llamar metodo
IF lo_badi IS BOUND.
CALL METHOD lo_badi->method_name
EXPORTING param = value
CHANGING data = ls_data.
ENDIF.

11. Activar/desactivar implementacion de BAdI

" Verificar programaticamente si BAdI esta activo
DATA: lo_badi TYPE REF TO zbadi_test.
GET BADI lo_badi.
" Verificar si existen implementaciones
DATA(lv_has_impl) = boolc( lo_badi IS BOUND ).
" En SE19:
" - Abrir implementacion
" - Marcar/desmarcar checkbox "Activo"
" - Activar

12. BAdI con contexto

" BAdI con contexto adicional
INTERFACE zif_context_badi PUBLIC.
METHODS: process
IMPORTING
iv_context TYPE string
is_data TYPE ty_data
EXPORTING
es_result TYPE ty_result.
ENDINTERFACE.
" Llamada con contexto para filtrado
DATA: lo_badi TYPE REF TO zbadi_context.
GET BADI lo_badi
FILTERS
context = 'SPECIAL_CASE'.
" Solo se llaman implementaciones para este contexto
CALL BADI lo_badi->process
EXPORTING
iv_context = 'SPECIAL_CASE'
is_data = ls_data
IMPORTING
es_result = ls_result.

13. Source Code Plugins (SCP)

" Source Code Plugins para ABAP Cloud
" Definido en la Behavior Definition
" managed implementation in class zbp_i_product;
"
" define behavior for ZI_Product
" {
" ...
" // Extension point para partners
" extension point productExtension;
" }
" Extension del partner implementa:
" enhance behavior for ZI_Product
" {
" extend productExtension
" {
" determination CalculateDiscount on modify { field price; }
" }
" }

14. User Exit (Legacy)

" User Exits clasicos (CMOD/SMOD)
" Se integran via Includes
" Include ZXaaau01 para Exit EXIT_SAPMM06E_001
FORM userexit_save_document_prepare.
" Logica especifica del cliente antes de guardar
IF sy-tcode = 'ME21N'.
" Modificar cabecera del pedido
ENDIF.
ENDFORM.

15. Vision general del Enhancement Framework

" Encontrar todas las ampliaciones de un objeto
" 1. SE84 - Repository Infosystem
" Buscar Enhancement Spots del objeto
" 2. Buscar en codigo:
" - ENHANCEMENT-POINT
" - ENHANCEMENT-SECTION
" - GET BADI
" 3. SE18 - Buscar definiciones de BAdI
" Analisis de uso muestra implementaciones
" 4. SE19 - Mostrar implementaciones
" Todas las implementaciones activas/inactivas

Crear Enhancement Spot propio (paso a paso)

1. SE18 -> Crear Enhancement Spot
- Nombre: ZES_MY_APPLICATION
- Ingresar descripcion breve
- Guardar
2. Agregar definicion de BAdI
- Nombre: ZBADI_MY_BADI
- Crear interfaz: ZIF_MY_BADI
- Definir metodos en la interfaz
- Opcional: Definir filtro
- Opcional: Especificar clase Fallback
3. Activar Enhancement Spot
4. Integrar en codigo:
DATA: lo_badi TYPE REF TO zbadi_my_badi.
GET BADI lo_badi.
CALL BADI lo_badi->my_method( ... ).
5. Crear implementacion (SE19)
- Enhancement Implementation: ZEI_MY_IMPL
- BAdI Implementation: ZBI_MY_IMPL
- Implementing Class: ZCL_MY_BADI_IMPL

Transacciones importantes

TransaccionDescripcion
SE18Definicion BAdI / Enhancement Spot
SE19Implementacion BAdI
SE80Repository Browser (Enhancements)
SE84Repository Infosystem
SPAUAjuste de modificaciones

Notas importantes / Mejores practicas

  • Preferir nuevos BAdIs (GET/CALL BADI) sobre clasicos.
  • Usar filtros para implementaciones especificas de contexto.
  • Definir clase Fallback para comportamiento por defecto.
  • Multiple Use si se permiten multiples implementaciones.
  • Enhancement Spots para puntos de ampliacion propios.
  • Las implementaciones pueden activarse/desactivarse.
  • No olvidar documentacion de la interfaz del BAdI.
  • En RAP usar Extension Points.
  • Sin modificaciones - siempre preferir ampliaciones.
  • Combinar con Unit Testing para testabilidad.